[
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file\n\nversion: 2\nupdates:\n  - package-ecosystem: \"cargo\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/clippy.yml",
    "content": "name: Run Clippy on PR\n\non:\n  repository_dispatch:\n    types: [clippy-command]\n\npermissions:\n  contents: write\n  pull-requests: write\n\njobs:\n  clippy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Resolve PR head\n        id: pr\n        run: |\n          echo \"repo=${{ github.event.client_payload.pull_request.head.repo.full_name }}\" >> \"$GITHUB_OUTPUT\"\n          echo \"ref=${{ github.event.client_payload.pull_request.head.ref }}\" >> \"$GITHUB_OUTPUT\"\n          echo \"number=${{ github.event.client_payload.pull_request.number }}\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Set token\n        id: token\n        run: |\n          if [ -n \"${{ secrets.REPO_SCOPED_TOKEN }}\" ]; then\n            echo \"token=${{ secrets.REPO_SCOPED_TOKEN }}\" >> \"$GITHUB_OUTPUT\"\n          else\n            echo \"token=${{ secrets.GITHUB_TOKEN }}\" >> \"$GITHUB_OUTPUT\"\n          fi\n\n      - name: Checkout PR head\n        uses: actions/checkout@v4\n        with:\n          repository: ${{ steps.pr.outputs.repo }}\n          ref: ${{ steps.pr.outputs.ref }}\n          token: ${{ steps.token.outputs.token }}\n          fetch-depth: 0\n\n      - name: Install Rust (stable + clippy)\n        uses: dtolnay/rust-toolchain@stable\n        with:\n          components: clippy\n\n      - name: Run cargo clippy\n        id: clippy\n        run: |\n          set +e\n          cargo clippy --all-targets --no-deps -- -D warnings > clippy_output.txt 2>&1\n          status=$?\n          echo \"status=$status\" >> $GITHUB_OUTPUT\n          exit 0\n\n      - name: Upload Clippy output\n        uses: actions/upload-artifact@v4\n        with:\n          name: clippy-log\n          path: clippy_output.txt\n\n      - name: Comment results on PR\n        uses: peter-evans/create-or-update-comment@v4\n        with:\n          token: ${{ steps.token.outputs.token }}\n          issue-number: ${{ steps.pr.outputs.number }}\n          body: |\n            🧹 `cargo clippy` has completed on `${{ steps.pr.outputs.ref }}`.\n            ${{ steps.clippy.outputs.status == '0' && '✅ No issues found!' || '⚠️ Warnings or errors detected – see Clippy log artifact.' }}\n"
  },
  {
    "path": ".github/workflows/fmt.yml",
    "content": "name: Check PR Formatting with cargo fmt\n\non:\n  repository_dispatch:\n    types: [fmt-command]\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  fmt:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Resolve PR head\n        id: pr\n        run: |\n          echo \"repo=${{ github.event.client_payload.pull_request.head.repo.full_name }}\" >> \"$GITHUB_OUTPUT\"\n          echo \"ref=${{ github.event.client_payload.pull_request.head.ref }}\" >> \"$GITHUB_OUTPUT\"\n          echo \"number=${{ github.event.client_payload.pull_request.number }}\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Checkout PR head\n        uses: actions/checkout@v4\n        with:\n          repository: ${{ steps.pr.outputs.repo }}\n          ref: ${{ steps.pr.outputs.ref }}\n          fetch-depth: 0\n\n      - name: Install Rust (stable + rustfmt)\n        uses: dtolnay/rust-toolchain@stable\n        with:\n          components: rustfmt\n\n      - name: Run cargo fmt\n        id: fmt\n        run: |\n          cargo fmt --all -- --check || echo \"changes_needed=true\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Comment on PR\n        uses: peter-evans/create-or-update-comment@v4\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          issue-number: ${{ steps.pr.outputs.number }}\n          body: |\n            ✅ `cargo fmt` completed on `${{ steps.pr.outputs.ref }}`.\n\n            ${{ \n              steps.fmt.outputs.changes_needed == 'true' && '❌ Formatting issues detected. Please run `cargo fmt --all` locally and push the fixes.' || \n              '🎉 Code is properly formatted. No action needed.'\n            }}\n\n"
  },
  {
    "path": ".github/workflows/linux_build_test.yml",
    "content": "name: LinuxBuildAndTest\npermissions:\n  contents: read\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Check tree\n      run: ./tree_check.sh\n    - name: Build\n      run: cargo build --verbose\n    - name: Run tests\n      run: ./ci_tests.sh\n"
  },
  {
    "path": ".github/workflows/macos_build_test.yml",
    "content": "name: MacOSBuildAndTest\npermissions:\n  contents: read\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build:\n\n    runs-on: macos-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Check tree\n      run: ./tree_check.sh\n    - name: Build\n      run: cargo build --verbose\n    - name: Run tests\n      run: ./ci_tests.sh\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "permissions:\n  contents: write\nname: release\non:\n  push:\n    tags: [\"v*.*.*\"]\n\njobs:\n  build:\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest]\n    runs-on: ${{ matrix.os }}\n    env:\n      BIN_TARGETS: \"aria\"\n      DYLIB_CRATES: \"aria_file aria_http aria_path aria_platform aria_regex aria_timezone aria_unicode\"\n      EXTRA_FILES: \"CHANGELOG.md\"\n      CARGO_TERM_COLOR: always\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - name: Get version\n        id: version\n        run: echo \"VERSION=${GITHUB_REF##refs/tags/}\" >> \"$GITHUB_ENV\"\n      - name: Build + package\n        shell: bash\n        run: ./package.sh\n      - name: Upload release assets\n        uses: softprops/action-gh-release@v2\n        with:\n          files: |\n            *.tgz\n            *.tgz.sha256\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/slash_clippy.yml",
    "content": "name: SlashClippy\n\non:\n  issue_comment:\n    types: [created]\n\npermissions:\n  contents: write\n  issues: write\n  pull-requests: read\n\njobs:\n  dispatch:\n    if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/clippy') }}\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n    steps:\n      - uses: peter-evans/slash-command-dispatch@v4\n        with:\n          token: ${{ secrets.SLASH_COMMAND_PAT }}\n          reaction-token: ${{ secrets.SLASH_COMMAND_PAT }}\n          commands: clippy\n          dispatch-type: repository\n          issue-type: pull-request\n          repository: ${{ github.repository }}\n"
  },
  {
    "path": ".github/workflows/slash_fmt.yml",
    "content": "name: SlashFmt\n\non:\n  issue_comment:\n    types: [created]\n\n# Needed:\n# - issues: write  → add 👍 reaction\n# - contents: write → fire repository_dispatch\npermissions:\n  contents: write\n  issues: write\n  pull-requests: read\n\njobs:\n  dispatch:\n    if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/fmt') }}\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n    steps:\n      - uses: peter-evans/slash-command-dispatch@v4\n        with:\n          # Use GITHUB_TOKEN now that it has write perms\n          token: ${{ secrets.SLASH_COMMAND_PAT  }}\n          reaction-token: ${{ secrets.SLASH_COMMAND_PAT  }}\n          commands: fmt\n          dispatch-type: repository\n          issue-type: pull-request\n          repository: ${{ github.repository }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Rust & Cargo\n/target\n\n# Profilers\ncallgrind.out.*\nperf.*\n\n# IDEs and Editors\n.vscode/\n.idea/\n*.swp\n*.swo\n\n# NPM\nnode_modules/\n\nout/\n\n# Aria-specific\nhistory.aria\n/vscode/aria/*.vsix\n\n# OS-specific\n.DS_Store\nThumbs.db\n\n.env"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "repos:\n-   repo: https://github.com/doublify/pre-commit-rust\n    rev: v1.0\n    hooks:\n    -   id: fmt\n    -   id: cargo-check\n    -   id: clippy\n-   repo: http://github.com/Quard/license-header-checker\n    rev: v0.1\n    hooks:\n    -   id: license-header-checker\n        files: \\.rs$\n        args:\n          - --comment-style\n          - \"//\"\n          - --license\n          - \"SPDX-License-Identifier: Apache-2.0\\n\"\n-   repo: http://github.com/Quard/license-header-checker\n    rev: v0.1\n    hooks:\n    -   id: license-header-checker\n        files: \\.aria$\n        args:\n          - --license\n          - \"SPDX-License-Identifier: Apache-2.0\\n\"\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).\nFor information on Aria's versioning scheme and release policy refer to [our Release Policy](https://arialang.github.io/release_policy.html).\n\n## [0.9.20251222]\n\n### Added\n\n- Values of builtin types can now be checked for `mixin`\n- Lists and strings allow wraparound indexing (e.g. `foo[-1]`)\n- shift-equal operators (`<<=` and `=>>`)\n- `\\r` is now recognized as a valid escape sequence\n- `JSONValue` prettyprints\n\n### Fixed\n\n- Multiplying a list or string by a negative integer returns an empty value\n- `File.writeln` now actually writes a newline\n- REPL input can now contain comments\n- `MixinRng.one_of` will fail if passed an empty list as input\n- String classes API now supports Unicode\n- Negative timestamps are now resolved correctly by `Instant`\n\n### Changed\n\n- in `match` statements, `case Foo(blah)` will fail if `Foo` does not have a payload instead of throwing a VM error\n- `String.hash` will return different values for anagrams\n\n### Deprecated\n\nNone\n\n### Removed\n\nNone\n\n## [0.9.20251118]\n\n### Added\n\n- Add support for `??` and `!!` operators to `Maybe` objects\n- Support for skipping and truncating iterators\n- `SipHash` support has been added to the standard library\n- Benchmarking utilities have been introduced to measure performance of code snippets\n- `List` can now be hashed if all its values are hashable\n- `Path.glob`\n- Initial support for widgets as a code organizing structure\n- Draft language server protocol (LSP) support for better IDE integration\n- It is now possible to write `x,y = y,x` for swapping values (multiple assignment) and to declare multiple variables in one statement (`val x = 1, y = 2;`)\n- `Map.frequency_map` has been added to create frequency maps from iterables\n- Intersection types (`TypeA & TypeB`) have been introduced\n\n### Fixed\n\n- `Map` would error if an object's `hash` returned a negative value; it now handles this correctly\n- It is now possible to write to a captured value without reading it\n- `isa` now works with mixins\n\n### Changed\n\n- `Path.entries()` returns an iterator instead of a list for better performance\n- `Path` operations consistently return `Maybe` / `Result` types for improved error handling\n- `Iterator` uses `Maybe` instead of `.done` for its iteration protocol\n- Hexadecimal literals are treated as unsigned integers\n- Aria now lives under the `arialang` GitHub organization (https://github.com/arialang/aria)\n\n### Deprecated\n\nNone\n\n### Removed\n\nNone\n"
  },
  {
    "path": "CODEOWNERS",
    "content": "# Failsafe, if nobody else can pick up a review, I can\n*    @egranata\n\n# List more specific code owners here\n.github/workflows/macos* @enricobolzonello\n\nnative-libs/path @ZocoLini\nlib/aria/io/path.aria @ZocoLini\n\n.github/workflows/slash* @dlkritter\n.github/workflows/clippy.yml @dlkritter\n.github/workflows/fmt.yml @dlkritter\n\nlsp @feznyng\nvscode/aria @feznyng\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[workspace]\nmembers = [\n    \"aria-bin\",\n    \"compiler-lib\",\n    \"lsp\",\n    \"native-libs/*\",\n    \"opcodes-lib\",\n    \"parser-lib\",\n    \"test-bin\",\n    \"vm-lib\",\n]\nresolver = \"2\"\n\n[profile.dist]\ninherits = \"release\"\ncodegen-units = 1\nlto = \"fat\"\ndebug = true\n\n[profile.pgo]\ninherits = \"release\"\nlto = \"thin\"\ndebug = true\n"
  },
  {
    "path": "Dockerfile",
    "content": "# syntax=docker/dockerfile:1\n# This Docker container installs Aria from prebuilt binaries on Ubuntu 24.04.\n# It can be used as a base image for Aria development or to run Aria in CI.\nFROM ubuntu:24.04\n\n# To build with a specific version, use:\n#   docker build --build-arg ARIA_VERSION=<version> --build-arg ARIA_BUILD_TIMESTAMP=<timestamp> --build-arg ARIA_EXPECTED_SHA256=<sha256> -t aria:<version> .\n# Example:\n#   docker build --build-arg ARIA_VERSION=0.9.20251220 --build-arg ARIA_BUILD_TIMESTAMP=20251220123456 --build-arg ARIA_EXPECTED_SHA256=47cb8d9de3a2229f1a403e1c616679811f085e819c1743e263c16c2c2d001d50 -t aria:0.9.20251220 .\nARG ARIA_VERSION=0.9.20251222\nARG ARIA_BUILD_TIMESTAMP=20251222174650\nARG ARIA_EXPECTED_SHA256=47cb8d9de3a2229f1a403e1c616679811f085e819c1743e263c16c2c2d001d50\n\nENV DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update \\\n    && apt-get install -y --no-install-recommends ca-certificates curl tar findutils \\\n    && rm -rf /var/lib/apt/lists/*\n\nRUN set -eux; \\\n    url=\"https://github.com/arialang/aria/releases/download/v${ARIA_VERSION}/aria-${ARIA_VERSION}-x86_64-unknown-linux-gnu-${ARIA_BUILD_TIMESTAMP}.tgz\"; \\\n    mkdir -p /usr/aria; \\\n    curl -fsSL \"$url\" -o /tmp/aria.tgz; \\\n    echo \"$ARIA_EXPECTED_SHA256 /tmp/aria.tgz\" | sha256sum -c -; \\\n    tar -xzf /tmp/aria.tgz -C /usr/aria; \\\n    rm -f /tmp/aria.tgz; \\\n    if [ ! -x /usr/aria/aria ]; then \\\n    aria_path=\"$(find /usr/aria -maxdepth 4 -type f -name aria -perm -111 | head -n1 || true)\"; \\\n    if [ -n \"$aria_path\" ] && [ \"$aria_path\" != \"/usr/aria/aria\" ]; then \\\n    ln -sf \"$aria_path\" /usr/aria/aria; \\\n    fi; \\\n    fi; \\\n    if [ ! -x /usr/aria/aria ]; then \\\n    echo \"Error: 'aria' executable not found under /usr/aria after extraction from $url\" >&2; \\\n    exit 1; \\\n    fi; \\\n    ln -sf /usr/aria/aria /usr/local/bin/aria\n\nCMD [\"bash\", \"-lc\", \"printf 'Aria is available in your environment. Start it by running \\\"aria\\\"\\\\n'; exec bash -i\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2025 Enrico Granata\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "README.md",
    "content": "# Aria: A Fresh, Safe, and Flexible Language for High-Level Development\n[![Linux Build](https://github.com/arialang/aria/actions/workflows/linux_build_test.yml/badge.svg?branch=master)](https://github.com/arialang/aria/actions/workflows/linux_build_test.yml)\n[![Mac Build](https://github.com/arialang/aria/actions/workflows/macos_build_test.yml/badge.svg?branch=master)](https://github.com/arialang/aria/actions/workflows/macos_build_test.yml)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Docs](https://img.shields.io/badge/Docs-Available-blue.svg)](https://arialang.github.io/)\n[![Contributors](https://img.shields.io/github/contributors/arialang/aria)](https://github.com/arialang/aria/graphs/contributors)\n\nPlease read [this post](https://arialang.github.io/blog/2026_02/post.html) for the latest update on Aria.\n\nWelcome to Aria. Aria is a modern, dynamic scripting language. It is meant to be a \"sweet spot\" language, easy to pick-up and with a good balance between ease of use, safety, and flexibility. Aria's design choices help you build great programs quickly.\n\nAria has modern, safer error handling: Aria replaces unreliable `None` pointer checks with a modern, multi-tiered approach to error handling. By emphasizing algebraic data types (e.g. `Maybe`), Aria makes errors explicit, safer, and easier to manage, with fewer runtime surprises.\n\n`null`, the [billion dollar mistake](https://softwareengineering.stackexchange.com/questions/413149/if-null-is-a-billion-dollar-mistake-what-is-the-solution-to-represent-a-non-ini) just does not exist in Aria, making code safer, easier to maintain and error handling more robust.\n\n```aria\nfunc main() {\n    val x = Int.parse(\"abc123\");\n    match x {\n        case Ok(val) => {\n            println(\"Parsed value: {0}\".format(val));\n        },\n        case Err(err) => {\n            println(\"Failed to parse integer: {0}\".format(err));\n        }\n    }\n}\n```\n\nAria is memory safe from the start: Aria’s virtual machine, built on the Rust ecosystem, ensures memory safety out of the box, protecting you from common pitfalls like data corruption and security vulnerabilities. This lets you focus on building without worrying about risks you cannot manage.\n\nMemory safety protects your code from issues such as memory corruption and dangling pointers. These issues can be hard to track down in large, complex systems. Aria brings these guarantees right from the start, so you can focus on building, not debugging.\n\nAria is designed for flexibility: Whether you need (some) type checks, an intuitive module system, or want to avoid the complexity of inheritance while still working with a modern object-based design, Aria adapts to your needs. It provides just enough structure to keep your code clean, without the overhead.\n\nAria’s object-based design uses composition instead of inheritance, which removes a lot of complexity from the language. This makes Aria easier to learn, your code easier to understand and maintain, and libraries more composable. Many parts of the Aria library adopt `mixin`s to bring code reuse, and you can too.\n\n```aria\nmixin Double {\n    func double() {\n        return this + this;\n    }\n}\n\nextension Int {\n    include Double\n}\n\nextension Float {\n    include Double\n}\n\nfunc main() {\n    println(3.double());\n    println(3.14.double());\n}\n```\n\nAria has a simple yet usable standard library, with date/time handling, networking, file system access, JSON support and more.\n\n```aria\nimport Instant from aria.date.instant;\n\nfunc main() {\n    val now = Instant.now();\n\n    println(\"The current date and time is: {0}\".format(now));\n}\n```\n\n```aria\nimport JsonValue from aria.json.parser;\n\nfunc main() {\n    val json_data = JsonValue.parse('{\"name\": \"Aria\", \"version\": \"0.9\"}')!.flatten();\n    println(\"Language: {0}, Version: {1}\".format(json_data[\"name\"], json_data[\"version\"]));\n}\n```\n\nAria is currently supported on Linux and macOS. Contributions for other operating systems are welcome and encouraged!\n\n## A Taste of Aria\n\nAria is easy to learn. Here's a [quick example](https://github.com/arialang/aria/blob/master/examples/github_user.aria) that fetches data from a web API and prints the result.\n\nIn this example, Aria fetches user data from GitHub’s API and prints the number of public repositories for a given user. This shows how simple it is to interact with external APIs and handle dynamic data in Aria.\n\n```aria\n# github_user.aria\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\n\nval whoami = \"egranata\";\n\nfunc main() {\n    val request = Request.new(\"https://api.github.com/users/{0}\".format(whoami));\n    request.headers[\"User-Agent\"] = \"AriaLang/1.0\";\n    val response = request.get();\n\n    if response.status_code == 200 {\n        val user_data = JsonValue.parse(response.content)!.flatten();\n        println(\"User {1} has {0} public repositories.\".format(user_data[\"public_repos\"], whoami));\n    } else {\n        println(\"Failed to fetch user data. Status: {0}\".format(response.status_code));\n    }\n}\n```\n\nRunning this is as simple as:\n```shell\n$ aria github_user.aria\nUser egranata has 5 public repositories.\n```\n\n## Getting Started\n\nReady to try Aria? Want to contribute to the language? Great! Whether you’re fixing bugs, adding features, or improving the documentation, we’d love your help!\n\nIf it's your first time contributing, check out [good starter bugs](https://github.com/arialang/aria/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22) or [help wanted](https://github.com/arialang/aria/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22help%20wanted%22) on GitHub.\n\nFor all this and more, visit [our website](https://arialang.github.io/)!\n"
  },
  {
    "path": "add_license_marker.sh",
    "content": "#!/bin/bash\nset -euo pipefail\n\nrust_license_comment=\"// SPDX-License-Identifier: Apache-2.0\"\naria_license_comment=\"# SPDX-License-Identifier: Apache-2.0\"\n\ncheck_mode=false\n[[ \"${1:-}\" == \"--check\" ]] && check_mode=true\n\nmissing=0\n\nhandle_file() {\n  local file=\"$1\" license=\"$2\"\n  if ! grep -qF \"$license\" \"$file\"; then\n    if $check_mode; then\n      echo \"Missing license in $file\"\n      missing=1\n    else\n      echo \"Adding license to $file\"\n      tmp=\"$(mktemp \"${file}.XXXX\")\"\n      { printf '%s\\n' \"$license\"; cat -- \"$file\"; } >\"$tmp\"\n      chmod --reference=\"$file\" \"$tmp\" 2>/dev/null || true\n      mv -f -- \"$tmp\" \"$file\"\n    fi\n  fi\n}\n\nwhile IFS= read -r -d '' file; do\n  case \"$file\" in\n    *.rs)   handle_file \"$file\" \"$rust_license_comment\" ;;\n    *.aria) handle_file \"$file\" \"$aria_license_comment\" ;;\n  esac\ndone < <(\n  find . -type d -name target -prune -o \\\n         -type f \\( -name '*.rs' -o -name '*.aria' \\) -print0\n)\n\nif $check_mode; then\n  if (( missing == 1 )); then exit 1; fi\n  echo \"All files have license info\"\nfi\n"
  },
  {
    "path": "aria",
    "content": "#!/bin/sh\ncargo build --workspace --profile ${ARIA_BUILD_CONFIG:-\"release\"}\n\nSELF_DIR=\"$(dirname \"$(readlink -f \"${BASH_SOURCE[0]}\")\")\"\nARIA_LIB_DIR=${ARIA_LIB_DIR:-\"${SELF_DIR}/lib:${SELF_DIR}/lib-test\"} cargo run --profile ${ARIA_BUILD_CONFIG:-\"release\"} --package aria-bin -- $@\n"
  },
  {
    "path": "aria-bin/Cargo.toml",
    "content": "[package]\nname = \"aria-bin\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[dependencies]\nopcodes-lib = { path = \"../opcodes-lib\" }\nparser-lib = { path = \"../parser-lib\" }\ncompiler-lib = { path = \"../compiler-lib\" }\nvm-lib = { path = \"../vm-lib\" }\nclap = { version = \"4.5.57\", features = [\"derive\"] }\nariadne = { git = \"https://github.com/zesterer/ariadne.git\", rev=\"b60b500\" }\nreedline = \"0.45.0\"\npprof = { version = \"0.15.0\", features = [\"cpp\", \"default\", \"flamegraph\", \"framehop\", \"framehop-unwinder\", \"perfmaps\", \"_protobuf\", \"prost-codec\"] }\n\n[[bin]]\nname = \"aria\"\npath = \"src/main.rs\"\n"
  },
  {
    "path": "aria-bin/src/error_reporting.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{collections::HashMap, vec};\n\nuse aria_compiler::do_compile::CompilationError;\nuse aria_parser::ast::{ParserError, SourcePointer};\nuse ariadne::{Color, Label, Report, ReportKind, Source};\nuse haxby_vm::{\n    error::{exception::VmException, vm_error::VmError},\n    vm::VirtualMachine,\n};\n\n#[derive(Default, Debug, Clone)]\npub struct StringCache {\n    buffers: HashMap<String, Source>,\n}\n\nimpl ariadne::Cache<String> for StringCache {\n    type Storage = String;\n\n    fn fetch(\n        &mut self,\n        path: &String,\n    ) -> Result<&Source<<Self as ariadne::Cache<String>>::Storage>, impl std::fmt::Debug> {\n        Ok::<&Source, Source>(&self.buffers[path])\n    }\n\n    #[allow(refining_impl_trait)]\n    fn display<'a>(&self, path: &'a String) -> Option<impl std::fmt::Display + 'a> {\n        Some(Box::new((*path).clone()))\n    }\n}\n\npub(crate) type PrintableReport<'a> = (\n    ariadne::Report<'a, (std::string::String, std::ops::Range<usize>)>,\n    StringCache,\n);\n\nfn build_report_from_msg_and_location<'a>(\n    msg: &str,\n    locations: Vec<SourcePointer>,\n) -> PrintableReport<'a> {\n    let config = ariadne::Config::default().with_index_type(ariadne::IndexType::Byte);\n    let magenta = Color::Magenta;\n    let mut report = Report::build(ReportKind::Error, (\"unknown\".to_owned(), 0..0))\n        .with_message(msg)\n        .with_config(config);\n    let mut cache = StringCache::default();\n    for (idx, loc) in locations.iter().enumerate() {\n        let loc = loc.clone();\n        report = report.with_label(\n            Label::new((\n                loc.buffer.name.clone(),\n                loc.location.start..loc.location.stop,\n            ))\n            .with_message(\"here\")\n            .with_order(idx as i32)\n            .with_color(magenta),\n        );\n        if !cache.buffers.contains_key(&loc.buffer.name) {\n            cache.buffers.insert(\n                loc.buffer.name.clone(),\n                Source::from((*loc.buffer.content).clone()),\n            );\n        }\n    }\n    (report.finish(), cache)\n}\n\npub(crate) fn print_report_from_vm_exception(vm: &mut VirtualMachine, exc: &VmException) {\n    let (report, cache) = build_report_from_vm_exception(vm, exc);\n    report.eprint(cache).unwrap();\n}\n\npub(crate) fn print_report_from_compiler_error(err: &CompilationError) {\n    let (report, cache) = build_report_from_compiler_error(err);\n    report.eprint(cache).unwrap();\n}\n\npub(crate) fn print_report_from_parser_error(err: &ParserError) {\n    let (report, cache) = build_report_from_parser_error(err);\n    report.eprint(cache).unwrap();\n}\n\npub(crate) fn print_report_from_vm_error(err: &VmError) {\n    let (report, cache) = build_report_from_vm_error(err);\n    report.eprint(cache).unwrap();\n}\n\npub(crate) fn build_report_from_vm_error<'a>(err: &VmError) -> PrintableReport<'a> {\n    let msg = err.reason.to_string();\n    if err.backtrace.is_empty() {\n        if let Some(loc) = &err.loc {\n            build_report_from_msg_and_location(&msg, vec![loc.clone()])\n        } else {\n            build_report_from_msg_and_location(&msg, vec![])\n        }\n    } else {\n        let backtraces: Vec<_> = err.backtrace.entries_iter().cloned().collect();\n        build_report_from_msg_and_location(&msg, backtraces)\n    }\n}\n\npub(crate) fn build_report_from_vm_exception<'a>(\n    vm: &mut VirtualMachine,\n    exc: &'a VmException,\n) -> PrintableReport<'a> {\n    let mut cur_frame = Default::default();\n    let msg = exc.value.prettyprint(&mut cur_frame, vm);\n    let backtraces: Vec<_> = exc.backtrace.entries_iter().cloned().collect();\n    build_report_from_msg_and_location(&msg, backtraces)\n}\n\npub(crate) fn build_report_from_compiler_error<'a>(\n    err: &'a CompilationError,\n) -> PrintableReport<'a> {\n    let msg = err.reason.to_string();\n    let loc = &err.loc;\n    build_report_from_msg_and_location(&msg, vec![loc.clone()])\n}\n\npub(crate) fn build_report_from_parser_error<'a>(err: &'a ParserError) -> PrintableReport<'a> {\n    let msg = &err.msg;\n    let loc = &err.loc;\n    build_report_from_msg_and_location(msg, vec![loc.clone()])\n}\n"
  },
  {
    "path": "aria-bin/src/error_reporting_test/expected.txt",
    "content": "main.aria:6:9\nutil.aria:3:13\nmain.aria:14:8\n"
  },
  {
    "path": "aria-bin/src/error_reporting_test/main.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport foo from util;\n\nfunc op(x,y) {\n    if x > 0 {\n        throw \"x is positive :(\";\n    }\n    return y + x;\n}\n\nfunc main() {\n    # this is reported as 6:9 (the location of the throw, not the location of the call)\n    # which is a bug, but I need to fix that orthogonally to this test\n    foo(op,3);\n}\n"
  },
  {
    "path": "aria-bin/src/error_reporting_test/util.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(f, n) {\n    return f(3,n);\n}\n"
  },
  {
    "path": "aria-bin/src/file_eval.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_compiler::{CompilationOptions, compile_from_ast};\nuse aria_parser::ast::{\n    SourceBuffer,\n    prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    source_to_ast,\n};\nuse haxby_vm::{\n    runtime_module::RuntimeModule,\n    vm::{VirtualMachine, VmOptions},\n};\n\nuse crate::{\n    Args,\n    error_reporting::{\n        print_report_from_compiler_error, print_report_from_parser_error,\n        print_report_from_vm_error, print_report_from_vm_exception,\n    },\n};\n\nimpl From<&Args> for CompilationOptions {\n    fn from(value: &Args) -> Self {\n        CompilationOptions {\n            optimize: !value.disable_optimizer,\n            dump_builder: value.dump_ir,\n        }\n    }\n}\n\n// To permit return Err(report_blah(x)) where report_blah(x) -> ()\n#[allow(clippy::unit_arg)]\nfn eval_buffer(\n    sb: SourceBuffer,\n    vm: &mut VirtualMachine,\n    args: &Args,\n) -> Result<RuntimeModule, ()> {\n    let ast = match source_to_ast(&sb) {\n        Ok(ast) => ast,\n        Err(err) => {\n            return Err(print_report_from_parser_error(&err));\n        }\n    };\n\n    if args.dump_ast {\n        let ast_buffer = PrintoutAccumulator::default();\n        let output = ast.prettyprint(ast_buffer).value();\n        println!(\"AST dump:\\n{output}\\n\");\n    }\n\n    let comp_opts = CompilationOptions::from(args);\n\n    let c_module = match compile_from_ast(&ast, &comp_opts) {\n        Ok(module) => module,\n        Err(err) => {\n            err.iter().for_each(print_report_from_compiler_error);\n            return Err(());\n        }\n    };\n\n    if args.dump_mod {\n        let mod_buffer = PrintoutAccumulator::default();\n        let output = c_module.prettyprint(mod_buffer).value();\n        println!(\"Module dump:\\n{output}\\n\");\n    }\n\n    let r_module = match RuntimeModule::new(vm, c_module) {\n        Ok(m) => m,\n        Err(err) => {\n            return Err(print_report_from_vm_error(&err.into()));\n        }\n    };\n\n    let r_module = match vm.load_into_module(\"\", r_module) {\n        Ok(rle) => match rle {\n            haxby_vm::vm::RunloopExit::Ok(m) => m.module,\n            haxby_vm::vm::RunloopExit::Exception(exc) => {\n                return Err(print_report_from_vm_exception(vm, &exc));\n            }\n        },\n        Err(err) => {\n            return Err(print_report_from_vm_error(&err));\n        }\n    };\n\n    let exec_result = vm.execute_module(&r_module);\n\n    match exec_result {\n        Ok(rle) => match rle {\n            haxby_vm::vm::RunloopExit::Ok(_) => Ok(r_module),\n            haxby_vm::vm::RunloopExit::Exception(exc) => {\n                Err(print_report_from_vm_exception(vm, &exc))\n            }\n        },\n        Err(err) => Err(print_report_from_vm_error(&err)),\n    }\n}\n\npub(crate) fn file_eval(path: &str, args: &Args) -> i32 {\n    use pprof::protos::Message;\n    use std::io::Write;\n\n    let mut vm = VirtualMachine::with_options(VmOptions::from(args));\n\n    let guard = if args.perf_trace_dest.is_some() {\n        match pprof::ProfilerGuardBuilder::default()\n            .frequency(1000)\n            .blocklist(&[\"libc\", \"libgcc\", \"pthread\", \"vdso\"])\n            .build()\n        {\n            Ok(guard) => Some(guard),\n            Err(err) => {\n                eprintln!(\"could not start profiler: {}\", err);\n                return 1;\n            }\n        }\n    } else {\n        None\n    };\n\n    let buffer = SourceBuffer::file(path);\n    let exit = match buffer {\n        Ok(src) => match eval_buffer(src, &mut vm, args) {\n            Ok(_) => 0,\n            Err(_) => 1,\n        },\n        Err(err) => {\n            println!(\"error reading source file: {err}\");\n            1\n        }\n    };\n\n    if let Some(guard) = guard\n        && let Ok(report) = guard.report().build()\n    {\n        let mut content = Vec::new();\n\n        if let Ok(mut dest_file) = std::fs::File::create(args.perf_trace_dest.as_ref().unwrap())\n            && let Ok(profile) = report.pprof()\n            && let Ok(_) = profile.encode(&mut content)\n        {\n            dest_file\n                .write_all(&content)\n                .expect(\"could not write pprof report\");\n            dest_file.flush().expect(\"could not flush pprof report\");\n        } else {\n            eprintln!(\"could not generate pprof report\");\n            return exit;\n        }\n    }\n\n    exit\n}\n"
  },
  {
    "path": "aria-bin/src/main.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nmod error_reporting;\nmod file_eval;\nmod repl_eval;\n\n#[cfg(test)]\nmod test;\n\nuse clap::Parser;\nuse haxby_vm::vm::{VirtualMachine, VmOptions};\n\n#[derive(Default, Parser, Debug)]\n#[command(author, name = \"aria\", version = env!(\"CARGO_PKG_VERSION\"), about, trailing_var_arg = true)]\nstruct Args {\n    /// The name of the program file to run\n    path: Option<String>,\n    /// The destination for the VM performance trace\n    #[arg(long(\"perf-trace-dest\"))]\n    perf_trace_dest: Option<String>,\n    /// Should the VM trace instruction execution\n    #[arg(long(\"trace-exec\"))]\n    #[cfg(debug_assertions)]\n    trace_exec: bool,\n    /// Should the VM dump the stack at each instruction\n    #[arg(long(\"trace-stack\"))]\n    #[cfg(debug_assertions)]\n    trace_stack: bool,\n    /// Should the AST be dumped after parsing\n    #[arg(long(\"dump-ast\"))]\n    dump_ast: bool,\n    /// Dump the compiler's intermediate representation\n    #[arg(long(\"dump-ir\"))]\n    dump_ir: bool,\n    /// Should the module be dumped after compilation\n    #[arg(long(\"dump-module\"))]\n    dump_mod: bool,\n    /// Turn off compile-time optimizations\n    #[arg(long(\"disable-optimizer\"))]\n    disable_optimizer: bool,\n    #[arg(trailing_var_arg = true)]\n    extra_args: Vec<String>,\n    #[arg(long(\"print-lib-path\"))]\n    print_lib_path: bool,\n    /// Turn off REPL preamble\n    #[arg(long(\"no-repl-preamble\"))]\n    no_repl_preamble: bool,\n}\n\nimpl From<&Args> for VmOptions {\n    fn from(value: &Args) -> Self {\n        let mut options = VmOptions::default();\n\n        #[cfg(debug_assertions)]\n        if value.trace_exec {\n            options.tracing = true;\n            if value.trace_stack {\n                options.dump_stack = true;\n            }\n        }\n\n        options.vm_args = value.extra_args.clone();\n\n        options\n    }\n}\n\nimpl Args {\n    fn check(&self) -> Vec<String> {\n        let mut ret = vec![];\n\n        if self.path.is_some() && self.no_repl_preamble {\n            ret.push(\"--no-repl-preamble has no effect when a file path is provided\".to_string());\n        }\n        if self.path.is_none() && self.perf_trace_dest.is_some() {\n            ret.push(\n                \"--perf-trace-dest has no effect when a file path is not provided\".to_string(),\n            );\n        }\n\n        ret\n    }\n}\n\nfn print_lib_paths() {\n    let lib_paths = VirtualMachine::get_aria_library_paths();\n    for path in lib_paths {\n        println!(\"{}\", path.display());\n    }\n}\n\nfn main_loop() -> i32 {\n    let args = Args::parse();\n\n    if args.print_lib_path {\n        print_lib_paths();\n        return 0;\n    }\n\n    let checks = args.check();\n    if !checks.is_empty() {\n        for check in checks {\n            eprintln!(\"Error: {}\", check);\n        }\n        return 1;\n    }\n\n    if let Some(path) = &args.path {\n        file_eval::file_eval(path, &args)\n    } else {\n        repl_eval::repl_eval(&args)\n    }\n}\n\nfn main() {\n    let exit_code = main_loop();\n    std::process::exit(exit_code);\n}\n"
  },
  {
    "path": "aria-bin/src/repl_eval.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::ops::DerefMut;\n\nuse aria_compiler::{CompilationOptions, compile_from_ast};\nuse aria_parser::ast::{\n    ExpressionStatement, SourceBuffer, TopLevelEntry,\n    prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    source_to_ast,\n};\nuse haxby_vm::{\n    runtime_module::RuntimeModule,\n    vm::{VirtualMachine, VmOptions},\n};\nuse reedline::{DefaultPrompt, Reedline, Validator};\n\nuse crate::{\n    Args,\n    error_reporting::{\n        build_report_from_compiler_error, build_report_from_parser_error,\n        build_report_from_vm_error, build_report_from_vm_exception,\n        print_report_from_compiler_error, print_report_from_parser_error,\n        print_report_from_vm_error, print_report_from_vm_exception,\n    },\n};\n\nstruct ReplValidator;\nimpl Validator for ReplValidator {\n    fn validate(&self, line: &str) -> reedline::ValidationResult {\n        use reedline::ValidationResult::{Complete, Incomplete};\n\n        let mut quote: Option<char> = None; // '\" or '\\''\n        let mut escaped = false;\n        let mut balance: Vec<char> = Vec::new();\n        let mut comment = false;\n\n        for c in line.chars() {\n            // inside string\n            if let Some(q) = quote {\n                if escaped {\n                    escaped = false;\n                    continue;\n                }\n                if c == '\\\\' {\n                    escaped = true;\n                    continue;\n                }\n                if c == q {\n                    quote = None;\n                }\n                continue;\n            } else if c == '#' || comment {\n                comment = c != '\\n';\n                continue;\n            } else {\n                match c {\n                    '\"' | '\\'' => quote = Some(c),\n                    '(' => balance.push(')'),\n                    '[' => balance.push(']'),\n                    '{' => balance.push('}'),\n                    ')' | ']' | '}' => {\n                        if !matches!(balance.last(), Some(&need) if need == c) {\n                            return Complete;\n                        } else {\n                            balance.pop();\n                        }\n                    }\n                    _ => {}\n                }\n            }\n        }\n\n        if quote.is_none() && balance.is_empty() {\n            Complete\n        } else {\n            Incomplete\n        }\n    }\n}\n\nstruct LineEditor {\n    line_editor: Reedline,\n    prompt: DefaultPrompt,\n}\n\nimpl LineEditor {\n    pub fn new() -> Self {\n        let validator = Box::new(ReplValidator);\n        let prompt = DefaultPrompt {\n            left_prompt: reedline::DefaultPromptSegment::Empty,\n            right_prompt: reedline::DefaultPromptSegment::Empty,\n        };\n        #[cfg(test)]\n        let line_editor = Reedline::create().with_validator(validator);\n        #[cfg(not(test))]\n        let line_editor = Reedline::create()\n            .with_validator(validator)\n            .with_history(Box::new(\n                reedline::FileBackedHistory::with_file(1024, \"history.aria\".into())\n                    .expect(\"history\"),\n            ));\n        Self {\n            line_editor,\n            prompt,\n        }\n    }\n}\n\nimpl LineEditor {\n    fn read_input(&mut self) -> (String, bool) {\n        let sig = self.line_editor.read_line(&self.prompt);\n        match sig {\n            Ok(reedline::Signal::Success(buffer)) => (buffer, false),\n            Ok(reedline::Signal::CtrlC) | Ok(reedline::Signal::CtrlD) | Err(_) => {\n                (String::new(), true)\n            }\n        }\n    }\n}\n\nfn is_call_to_print_or_println(expr: &ExpressionStatement) -> bool {\n    if let Some(v) = &expr.val {\n        let (is_call, name) = v.is_function_call();\n        return is_call && matches!(name, Some(\"print\") | Some(\"println\"));\n    }\n    false\n}\n\nfn massage_ast_for_repl(ast: &mut aria_parser::ast::ParsedModule) -> bool {\n    if ast.entries.is_empty() {\n        return false;\n    }\n    let idx = ast.entries.len() - 1;\n\n    let TopLevelEntry::ExpressionStatement(expr) = &ast.entries[idx] else {\n        return false;\n    };\n    if is_call_to_print_or_println(expr) {\n        return false;\n    }\n    let Some(val) = &expr.val else { return false };\n\n    let new_node = val.call_function_passing_me(\"println\");\n    ast.entries[idx] = TopLevelEntry::ExpressionStatement(ExpressionStatement {\n        loc: val.loc().clone(),\n        val: Some(new_node),\n    });\n    true\n}\n\n#[cfg(test)]\npub struct ReplStepResult {\n    pub stdout: String,\n    #[allow(dead_code)]\n    pub stderr: String,\n    pub ok: bool,\n}\n\npub struct Repl<'a> {\n    vm: VirtualMachine,\n    module: RuntimeModule,\n    args: &'a Args,\n    counter: u64,\n}\n\nimpl<'a> Repl<'a> {\n    #[allow(clippy::unit_arg)]\n    pub fn new(vm_options: VmOptions, args: &'a Args) -> Result<Self, ()> {\n        let mut vm = VirtualMachine::with_options(vm_options);\n        let repl_module_preamble = if args.no_repl_preamble {\n            \"\"\n        } else {\n            include_str!(\"repl_preamble.aria\")\n        };\n\n        let sb = SourceBuffer::stdin_with_name(repl_module_preamble, \"repl\");\n        let ast = match source_to_ast(&sb) {\n            Ok(ast) => ast,\n            Err(err) => {\n                return Err(print_report_from_parser_error(&err));\n            }\n        };\n\n        let comp_opts = CompilationOptions::default();\n\n        let c_module = match compile_from_ast(&ast, &comp_opts) {\n            Ok(module) => module,\n            Err(err) => {\n                err.iter().for_each(print_report_from_compiler_error);\n                return Err(());\n            }\n        };\n\n        let r_module = match RuntimeModule::new(&mut vm, c_module) {\n            Ok(m) => m,\n            Err(err) => {\n                return Err(print_report_from_vm_error(&err.into()));\n            }\n        };\n\n        let r_module = match vm.load_into_module(\"repl\", r_module) {\n            Ok(rle) => match rle {\n                haxby_vm::vm::RunloopExit::Ok(m) => m.module,\n                haxby_vm::vm::RunloopExit::Exception(exc) => {\n                    return Err(print_report_from_vm_exception(&mut vm, &exc));\n                }\n            },\n            Err(err) => {\n                return Err(print_report_from_vm_error(&err));\n            }\n        };\n\n        vm.inject_imported_module(\"repl\", r_module.clone());\n        Ok(Repl {\n            vm,\n            module: r_module,\n            args,\n            counter: 0,\n        })\n    }\n\n    fn try_parse_source(\n        &mut self,\n        buffer: &SourceBuffer,\n    ) -> Result<aria_parser::ast::ParsedModule, aria_parser::ast::ParserError> {\n        source_to_ast(buffer)\n    }\n\n    #[allow(clippy::unit_arg)]\n    pub fn process_buffer(&mut self, buffer: &str) -> Result<RuntimeModule, ()> {\n        let module_name: String = format!(\"__repl_chunk_{}\", self.counter);\n        self.counter += 1;\n\n        let module_source_code = format!(\"import * from repl;\\n{}\\n\", buffer);\n        let sb = SourceBuffer::stdin_with_name(&module_source_code, &module_name);\n\n        let mut parsed_source = self.try_parse_source(&sb);\n        if parsed_source.is_err() && !(buffer.ends_with('}') || buffer.ends_with(';')) {\n            let buffer_with_semicolon = format!(\"{};\", module_source_code);\n            let sb2 = SourceBuffer::stdin_with_name(&buffer_with_semicolon, &module_name);\n            let parsed_source2 = self.try_parse_source(&sb2);\n            if parsed_source2.is_ok() {\n                parsed_source = parsed_source2;\n            }\n        }\n\n        let mut ast = match parsed_source {\n            Ok(ast) => ast,\n            Err(err) => {\n                return Err(self.print_error_report(build_report_from_parser_error(&err)));\n            }\n        };\n\n        let mutated = massage_ast_for_repl(&mut ast);\n\n        if self.args.dump_ast {\n            let ast_buffer = PrintoutAccumulator::default();\n            let output = ast.prettyprint(ast_buffer).value();\n            println!(\"AST dump:\\n{output}\\n\");\n            if mutated {\n                println!(\"note: AST mutated for REPL purposes\");\n            }\n        }\n\n        let comp_opts = CompilationOptions::default();\n\n        let c_module = match compile_from_ast(&ast, &comp_opts) {\n            Ok(module) => module,\n            Err(err) => {\n                err.iter()\n                    .for_each(|e| self.print_error_report(build_report_from_compiler_error(e)));\n                return Err(());\n            }\n        };\n\n        if self.args.dump_mod {\n            let mod_buffer = PrintoutAccumulator::default();\n            let output = c_module.prettyprint(mod_buffer).value();\n            println!(\"Module dump:\\n{output}\\n\");\n        }\n\n        let r_module = match RuntimeModule::new(&mut self.vm, c_module) {\n            Ok(m) => m,\n            Err(err) => {\n                return Err(self.print_error_report(build_report_from_vm_error(&err.into())));\n            }\n        };\n\n        if r_module\n            .lift_all_symbols_from_other(&self.module, &self.vm)\n            .is_err()\n        {\n            return Err(());\n        }\n\n        let load_result = self.vm.load_into_module(\"repl\", r_module);\n        match load_result {\n            Ok(rle) => match rle {\n                haxby_vm::vm::RunloopExit::Ok(m) => {\n                    let new_module = m.module;\n                    let _ = self\n                        .module\n                        .lift_all_symbols_from_other(&new_module, &self.vm);\n                    Ok(new_module)\n                }\n                haxby_vm::vm::RunloopExit::Exception(exc) => {\n                    let report = build_report_from_vm_exception(&mut self.vm, &exc);\n                    Err(self.print_error_report(report))\n                }\n            },\n            Err(err) => Err(self.print_error_report(build_report_from_vm_error(&err))),\n        }\n    }\n\n    fn print_error_report(&mut self, report: crate::error_reporting::PrintableReport<'_>) {\n        let console_rc = self.vm.console();\n        let mut console_borrow = console_rc.borrow_mut();\n        let console = console_borrow.deref_mut();\n        let _ = report.0.write(report.1, console);\n    }\n\n    #[cfg(test)]\n    pub fn eval_line(&mut self, src: &str) -> ReplStepResult {\n        fn diff(before: &str, after: &str) -> String {\n            if after.len() >= before.len() {\n                after[before.len()..].to_string()\n            } else {\n                String::new()\n            }\n        }\n\n        let before_console = self\n            .vm\n            .console()\n            .borrow()\n            .as_any()\n            .downcast_ref::<haxby_vm::console::TestConsole>()\n            .unwrap()\n            .clone();\n        let before_stdout = before_console.stdout.clone();\n        let before_stderr = before_console.stderr.clone();\n\n        let ok = self.process_buffer(src).is_ok();\n\n        let after_console = self\n            .vm\n            .console()\n            .borrow()\n            .as_any()\n            .downcast_ref::<haxby_vm::console::TestConsole>()\n            .unwrap()\n            .clone();\n        let after_stdout = after_console.stdout.clone();\n        let after_stderr = after_console.stderr.clone();\n\n        ReplStepResult {\n            stdout: diff(&before_stdout, &after_stdout),\n            stderr: diff(&before_stderr, &after_stderr),\n            ok,\n        }\n    }\n}\n\npub(crate) fn repl_eval(args: &Args) -> i32 {\n    let vm_opts = VmOptions::from(args);\n    let mut repl = Repl::new(vm_opts, args).unwrap();\n\n    let mut ed = LineEditor::new();\n\n    loop {\n        let (input, eof) = ed.read_input();\n\n        if eof {\n            break;\n        }\n\n        let input = input.trim();\n        if input.is_empty() {\n            continue;\n        } else if input == \":quit\" {\n            break;\n        } else {\n            let _ = repl.process_buffer(input);\n        }\n    }\n\n    0 // REPL will always exit 0\n}\n"
  },
  {
    "path": "aria-bin/src/repl_preamble.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport File from aria.io.file;\nimport Path from aria.io.path;\nimport Request from aria.network.request;\nimport Map from aria.structures.map;\nimport Regex from aria.string.regex;\n\nimport aria.iterator.mixin;\nimport aria.numerics.float.exp;\nimport aria.numerics.float.trig;\nimport aria.numerics.int.pow;\n\nimport aria.range.int_extension;\n"
  },
  {
    "path": "aria-bin/src/test.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::{cell::RefCell, rc::Rc};\n\nuse haxby_vm::console::TestConsole;\n\nuse crate::{Args, repl_eval::Repl};\n\nfn build_test_repl<'a>(cmdline_options: &'a Args) -> Repl<'a> {\n    let console = Rc::new(RefCell::new(TestConsole::default()));\n    let vm_options = haxby_vm::vm::VmOptions {\n        console: console.clone(),\n        ..Default::default()\n    };\n    Repl::new(vm_options, cmdline_options).unwrap()\n}\n\nfn run_check_repl_line(\n    repl: &mut Repl,\n    line: &str,\n    ok: bool,\n    must_include_stdout: &[&str],\n    must_include_stderr: &[&str],\n) {\n    let diff = repl.eval_line(line);\n\n    assert!(diff.ok == ok);\n\n    for expected in must_include_stdout {\n        assert!(\n            diff.stdout.contains(expected),\n            \"stdout ( {} ) did not contain expected ( {} )\",\n            diff.stdout,\n            expected\n        );\n    }\n\n    for expected in must_include_stderr {\n        assert!(\n            diff.stderr.contains(expected),\n            \"stderr ( {} ) did not contain expected ( {} )\",\n            diff.stderr,\n            expected\n        );\n    }\n}\n\nfn run_passing_repl_line(repl: &mut Repl, line: &str, must_include_stdout: &[&str]) {\n    run_check_repl_line(repl, line, true, must_include_stdout, &[])\n}\n\n#[test]\nfn repl_can_print_integers() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"42;\", &[\"42\"]);\n    run_passing_repl_line(&mut repl, \"3 + 4;\", &[\"7\"]);\n}\n\n#[test]\nfn repl_can_call_functions() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"func foo(x) { return x + 1; }\", &[]);\n    run_passing_repl_line(&mut repl, \"foo(12);\", &[\"13\"]);\n}\n\n#[test]\nfn repl_can_define_structs() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nstruct Pair {\n        type func new(x,y) {\n            return alloc(This) {\n                .x = x, .y = y,\n            };\n        }\n}\n    \"#,\n        &[],\n    );\n\n    run_passing_repl_line(&mut repl, \"val p = Pair.new(4,5);\", &[]);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nextension Pair {\n        func prettyprint() {\n            return \"Pair({0},{1})\".format(this.x,this.y);\n        }\n}\n    \"#,\n        &[],\n    );\n\n    run_passing_repl_line(&mut repl, \"p;\", &[\"Pair(4,5)\"]);\n}\n\n#[test]\nfn repl_can_use_if_statement() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"val x = 4;\", &[]);\n    run_passing_repl_line(&mut repl, \"if (x > 2) { println(x + 1); }\", &[\"5\"]);\n    run_passing_repl_line(&mut repl, \"if (x > 4) { println(x + 1); }\", &[\"\"]);\n}\n\n#[test]\nfn repl_can_use_for_statement() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"val l = [1,2,3,4,5,6];\", &[]);\n    run_passing_repl_line(\n        &mut repl,\n        \"for i in l { println(i); }\",\n        &[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"],\n    );\n}\n\n#[test]\nfn repl_can_use_while_statement() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"val n = 10;\", &[]);\n    run_passing_repl_line(\n        &mut repl,\n        \"while n > 0 { n -= 2; println(n); }\",\n        &[\"8\", \"6\", \"4\", \"2\", \"0\"],\n    );\n}\n\n#[test]\nfn repl_can_use_match_statement() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"val n = 10;\", &[]);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nmatch n {\n        > 10 => {\n            println(\"Greater than 10\");\n        }\n} else {\n        println(\"10 or less\");\n}\n\"#,\n        &[\"10 or less\"],\n    );\n}\n\n#[test]\nfn repl_printout_maybe() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nstruct Pair {\n    type func new(x,y) {\n        return alloc(This) {\n            .x = x, .y = y,\n        };\n    }\n    func prettyprint() {\n        return \"Pair({0},{1})\".format(this.x,this.y);\n    }\n}\n\"#,\n        &[\"\"],\n    );\n\n    run_passing_repl_line(\n        &mut repl,\n        \"Maybe::Some(Pair.new(4,5));\",\n        &[\"Some(Pair(4,5))\"],\n    );\n    run_passing_repl_line(&mut repl, \"Maybe::None;\", &[\"None\"]);\n}\n\n#[test]\nfn repl_adds_semicolon() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"val x = 1\", &[]);\n    run_passing_repl_line(&mut repl, \"val y = 2\", &[]);\n    run_passing_repl_line(&mut repl, \"2 * y + x\", &[\"5\"]);\n}\n\n#[test]\nfn repl_preamble_works() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"3.pow(2)\", &[\"9\"]);\n    run_passing_repl_line(&mut repl, \"val m = Map.new(); m[1] = 'one'; m[1]\", &[\"one\"]);\n    run_passing_repl_line(&mut repl, \"m.get(4)\", &[\"None\"]);\n}\n\n#[test]\nfn repl_skips_preamble() {\n    let cmdline_options = Args {\n        no_repl_preamble: true,\n        ..Default::default()\n    };\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_check_repl_line(\n        &mut repl,\n        \"3.pow(2)\",\n        false,\n        &[\"identifier 'pow' not found\"],\n        &[],\n    );\n}\n\n#[test]\nfn repl_op_count_error() {\n    let cmdline_options = Args {\n        no_repl_preamble: true,\n        ..Default::default()\n    };\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_check_repl_line(\n        &mut repl,\n        \"struct Foo { operator[]=() { return 1; } }\",\n        false,\n        &[\"operator []= accepts at least 1 arguments, but 0 were declared\"],\n        &[],\n    );\n\n    run_check_repl_line(\n        &mut repl,\n        \"struct Foo { operator + (a,b,c) { return 1; } }\",\n        false,\n        &[\"operator + accepts exactly 1 arguments, but 3 were declared\"],\n        &[],\n    );\n}\n\n#[test]\nfn repl_test_printf() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(&mut repl, \"'hello = {0}'.printf(42);\", &[\"hello = 42\"]);\n    run_passing_repl_line(\n        &mut repl,\n        \"'hello = {0} hi = {1}\\n'.printf(42, 43);\",\n        &[\"hello = 42 hi = 43\\n\"],\n    );\n}\n\n#[test]\nfn repl_test_invalid_literal() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_check_repl_line(\n        &mut repl,\n        \"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\",\n        false,\n        &[\"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF is not a valid literal\"],\n        &[],\n    );\n}\n\n#[test]\nfn repl_allows_comments() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nfunc foo() {\n# this is a comment\nreturn # this is another comment\n (\n    12345 # comment after expression\n );\n}\n\"#,\n        &[],\n    );\n    run_passing_repl_line(&mut repl, \"foo();\", &[\"12345\"]);\n}\n\n#[test]\nfn repl_handles_hashtag_in_string() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nfunc foo() {\n# this is a comment\nreturn '#arialang';\n}\n\"#,\n        &[],\n    );\n    run_passing_repl_line(&mut repl, \"foo();\", &[\"#arialang\"]);\n}\n\n#[test]\nfn repl_test_oneof_from_empty_list() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_check_repl_line(\n        &mut repl,\n        r#\"\nimport XorshiftRng from aria.rng.xorshift;\nval x = XorshiftRng.new();\nx.one_of([])\n        \"#,\n        false,\n        &[\"operation failed: cannot choose from empty list\"],\n        &[],\n    );\n}\n\n#[test]\nfn repl_includes_ranges() {\n    let cmdline_options = Args::default();\n    let mut repl = build_test_repl(&cmdline_options);\n\n    run_passing_repl_line(\n        &mut repl,\n        r#\"\nval x = 0;\nfor i in 0.to(5) { x += i; }\n\"i = {0}\\n\".printf(x);\n\"#,\n        &[\"i = 10\"],\n    );\n}\n"
  },
  {
    "path": "aria-bin/test_assert.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo() {\n    assert false;\n}\n\nfunc main() {\n    return foo();\n}\n"
  },
  {
    "path": "aria-bin/test_uncaught_exception.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo() {\n    return 3 / 0;\n}\n\nfunc main() {\n    return foo();\n}\n"
  },
  {
    "path": "b",
    "content": "#!/usr/bin/env bash\nset -e\n\nprint_usage() {\n    echo \"Usage: $0 <command> <bench>\"\n    echo \"command: bench, micro, perf, time, valgrind\"\n    echo \"bench: Name or partial name of the benchmark to run\"\n}\n\nCOMMAND=$1\nBENCH=$2\n\nif [ -z \"$COMMAND\" ]; then\n    print_usage\n    exit 1\nfi\n\nSELF_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nARIA_BUILD_CONFIG=\"${ARIA_BUILD_CONFIG:-release}\"\nCPU_AFFINITY_MASK=\"${CPU_AFFINITY_MASK:-0x1}\"\nif [ -z \"${ARIA_EXECUTABLE:-}\" ]; then\n    cargo build --profile \"$ARIA_BUILD_CONFIG\" --bin aria\n    TARGET_DIR=$(cd \"$SELF_DIR\" && cargo metadata --format-version 1 --no-deps 2>/dev/null | jq -r '.target_directory // empty' 2>/dev/null || true)\n    if [ -z \"$TARGET_DIR\" ]; then\n        TARGET_DIR=\"${SELF_DIR}/../target\"\n    fi\n    ARIA_EXECUTABLE=\"${TARGET_DIR}/${ARIA_BUILD_CONFIG}/aria\"\nfi\nexport ARIA_EXECUTABLE\nARIA_LIB_DIR=\"${ARIA_LIB_DIR:-${SELF_DIR}/lib:${SELF_DIR}/lib-test}\"\n\nexport ARIA_LIB_DIR=\"$ARIA_LIB_DIR\"\n\nif [ \"$COMMAND\" = \"bench\" ]; then\n    cargo bench --profile \"$ARIA_BUILD_CONFIG\" --package vm-lib \"$BENCH\"\nelif [ \"$COMMAND\" = \"micro\" ]; then\n    if [ ! -f \"$BENCH\" ]; then\n        BENCH=\"${SELF_DIR}/microbenchmarks/${BENCH}.aria\"\n    fi\n    ARIA_LIB_DIR=\"${ARIA_LIB_DIR}:${SELF_DIR}/microbenchmarks\"\n    export ARIA_LIB_DIR\n    if command -v taskset >/dev/null 2>&1; then\n        exec taskset \"$CPU_AFFINITY_MASK\" \"${ARIA_EXECUTABLE}\" \"$BENCH\" \"${@:3}\"\n    else\n        exec \"${ARIA_EXECUTABLE}\" \"$BENCH\" \"${@:3}\"\n    fi\nelse\n    OUTPUT=$(cargo bench --no-run --profile \"$ARIA_BUILD_CONFIG\" --package vm-lib \"$BENCH\" 2>&1)\n    echo \"$OUTPUT\"\n    EXECUTABLE_PATH=$(echo \"$OUTPUT\" | grep \"^  Executable\" | tail -n1 | awk '{gsub(/[()]/,\"\",$NF); print $NF}')\n\n    case \"$COMMAND\" in\n        perf)\n            echo \"Running with perf...\"\n            perf record -g \"$EXECUTABLE_PATH\" \"$BENCH\"\n            ;;\n        valgrind)\n            echo \"Running with Valgrind Callgrind...\"\n            ulimit -n 4096\n            valgrind --tool=callgrind \"$EXECUTABLE_PATH\" \"$BENCH\"\n            ;;\n        time)\n            echo \"Running with time...\"\n            time \"$EXECUTABLE_PATH\" \"$BENCH\"\n            ;;\n        *)\n            echo \"Invalid command\"\n            print_usage\n            exit 1\n            ;;\n    esac\nfi"
  },
  {
    "path": "ci_tests.sh",
    "content": "#!/usr/bin/env bash\nset -e\n\nSELF_DIR=\"$(dirname \"$(readlink -f \"${BASH_SOURCE[0]}\")\")\"\n\n${SELF_DIR}/t  --sequential\n"
  },
  {
    "path": "compiler-lib/Cargo.toml",
    "content": "[package]\nname = \"compiler-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_compiler\"\npath = \"src/lib.rs\"\n\n[dependencies]\npest = \"2.8.5\"\npest_derive = \"2.8.5\"\nopcodes-lib = { path = \"../opcodes-lib\" }\nparser-lib = { path = \"../parser-lib\" }\nenum-as-inner = \"0.7.0\"\nthiserror = \"2.0.18\"\nlazy_static = \"1.5.0\"\n"
  },
  {
    "path": "compiler-lib/src/bc_reader.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::{BuiltinTypeId, BuiltinValueId, Opcode};\n\npub struct BytecodeReader {\n    data: Vec<u8>,\n    idx: usize,\n}\n\nimpl TryFrom<&[u8]> for BytecodeReader {\n    type Error = DecodeError;\n\n    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {\n        if value.len() > u16::MAX as usize {\n            Err(DecodeError::DataTooLarge)\n        } else {\n            Ok(Self {\n                data: value.to_vec(),\n                idx: 0,\n            })\n        }\n    }\n}\n\n#[derive(Clone, thiserror::Error, PartialEq, Eq, Debug)]\npub enum DecodeError {\n    #[error(\"bytecode exceeds maximum allowed size\")]\n    DataTooLarge,\n\n    #[error(\"reached end of stream\")]\n    EndOfStream,\n\n    #[error(\"insufficient data for decoding\")]\n    InsufficientData,\n\n    #[error(\"{0} is not a known opcode\")]\n    UnknownOpcode(u8),\n\n    #[error(\"{1} is not a valid operand for opcode {0}\")]\n    UnknownOperand(u8, u8),\n}\n\npub type DecodeResult<T> = Result<T, DecodeError>;\n\nimpl BytecodeReader {\n    #[inline]\n    fn read_u8(&mut self) -> DecodeResult<u8> {\n        if self.idx < self.data.len() {\n            let val = self.data[self.idx];\n            self.idx += 1;\n            Ok(val)\n        } else {\n            Err(DecodeError::EndOfStream)\n        }\n    }\n\n    #[inline]\n    fn read_u16(&mut self) -> DecodeResult<u16> {\n        if self.idx + 1 < self.data.len() {\n            let val = u16::from_le_bytes([self.data[self.idx], self.data[self.idx + 1]]);\n            self.idx += 2;\n            Ok(val)\n        } else {\n            Err(DecodeError::EndOfStream)\n        }\n    }\n\n    #[inline]\n    fn read_u32(&mut self) -> DecodeResult<u32> {\n        if self.idx + 3 < self.data.len() {\n            let val = u32::from_le_bytes([\n                self.data[self.idx],\n                self.data[self.idx + 1],\n                self.data[self.idx + 2],\n                self.data[self.idx + 3],\n            ]);\n            self.idx += 4;\n            Ok(val)\n        } else {\n            Err(DecodeError::EndOfStream)\n        }\n    }\n\n    pub fn jump_to_index(&mut self, idx: usize) {\n        self.idx = idx;\n    }\n\n    pub fn get_index(&self) -> usize {\n        self.idx\n    }\n\n    pub fn read_opcode(&mut self) -> DecodeResult<Opcode> {\n        let next = self.read_u8()?;\n\n        match next {\n            haxby_opcodes::OPCODE_NOP => Ok(Opcode::Nop),\n            haxby_opcodes::OPCODE_PUSH => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| Ok(Opcode::Push(b))),\n            haxby_opcodes::OPCODE_PUSH_0 => Ok(Opcode::Push0),\n            haxby_opcodes::OPCODE_PUSH_1 => Ok(Opcode::Push1),\n            haxby_opcodes::OPCODE_PUSH_TRUE => Ok(Opcode::PushTrue),\n            haxby_opcodes::OPCODE_PUSH_FALSE => Ok(Opcode::PushFalse),\n            haxby_opcodes::OPCODE_PUSH_BUILTIN_TYPE => {\n                let arg0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let bt_id = match BuiltinTypeId::try_from(arg0) {\n                    Ok(id) => id,\n                    Err(_) => {\n                        return Err(DecodeError::UnknownOperand(next, arg0));\n                    }\n                };\n                Ok(Opcode::PushBuiltinTy(bt_id))\n            }\n            haxby_opcodes::OPCODE_PUSH_RUNTIME_VALUE => {\n                let arg0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let bt_id = match BuiltinValueId::try_from(arg0) {\n                    Ok(id) => id,\n                    Err(_) => {\n                        return Err(DecodeError::UnknownOperand(next, arg0));\n                    }\n                };\n                Ok(Opcode::PushRuntimeValue(bt_id))\n            }\n            haxby_opcodes::OPCODE_POP => Ok(Opcode::Pop),\n            haxby_opcodes::OPCODE_DUP => Ok(Opcode::Dup),\n            haxby_opcodes::OPCODE_SWAP => Ok(Opcode::Swap),\n            haxby_opcodes::OPCODE_COPY => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| Ok(Opcode::Copy(b))),\n            haxby_opcodes::OPCODE_ADD => Ok(Opcode::Add),\n            haxby_opcodes::OPCODE_SUB => Ok(Opcode::Sub),\n            haxby_opcodes::OPCODE_MUL => Ok(Opcode::Mul),\n            haxby_opcodes::OPCODE_DIV => Ok(Opcode::Div),\n            haxby_opcodes::OPCODE_REM => Ok(Opcode::Rem),\n            haxby_opcodes::OPCODE_EQ => Ok(Opcode::Equal),\n            haxby_opcodes::OPCODE_GT => Ok(Opcode::GreaterThan),\n            haxby_opcodes::OPCODE_LT => Ok(Opcode::LessThan),\n            haxby_opcodes::OPCODE_GTE => Ok(Opcode::GreaterThanEqual),\n            haxby_opcodes::OPCODE_LTE => Ok(Opcode::LessThanEqual),\n            haxby_opcodes::OPCODE_NEG => Ok(Opcode::Neg),\n            haxby_opcodes::OPCODE_SHL => Ok(Opcode::ShiftLeft),\n            haxby_opcodes::OPCODE_SHR => Ok(Opcode::ShiftRight),\n            haxby_opcodes::OPCODE_NOT => Ok(Opcode::Not),\n            haxby_opcodes::OPCODE_READ_LOCAL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::ReadLocal(b))\n                }),\n            haxby_opcodes::OPCODE_WRITE_LOCAL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::WriteLocal(b))\n                }),\n            haxby_opcodes::OPCODE_TYPEDEF_LOCAL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::TypedefLocal(b))\n                }),\n            haxby_opcodes::OPCODE_READ_NAMED => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::ReadNamed(b))\n                }),\n            haxby_opcodes::OPCODE_WRITE_NAMED => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::WriteNamed(b))\n                }),\n            haxby_opcodes::OPCODE_TYPEDEF_NAMED => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::TypedefNamed(b))\n                }),\n            haxby_opcodes::OPCODE_READ_INDEX => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::ReadIndex(b))\n                }),\n            haxby_opcodes::OPCODE_WRITE_INDEX => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::WriteIndex(b))\n                }),\n            haxby_opcodes::OPCODE_READ_ATTRIBUTE => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::ReadAttribute(b))\n                }),\n            haxby_opcodes::OPCODE_WRITE_ATTRIBUTE => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::WriteAttribute(b))\n                }),\n            haxby_opcodes::OPCODE_READ_ATTRIBUTE_SYMBOL => self\n                .read_u32()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::ReadAttributeSymbol(b))\n                }),\n            haxby_opcodes::OPCODE_WRITE_ATTRIBUTE_SYMBOL => self\n                .read_u32()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::WriteAttributeSymbol(b))\n                }),\n            haxby_opcodes::OPCODE_READ_UPLEVEL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::ReadUplevel(b))\n                }),\n            haxby_opcodes::OPCODE_LOGICAL_AND => Ok(Opcode::LogicalAnd),\n            haxby_opcodes::OPCODE_LOGICAL_OR => Ok(Opcode::LogicalOr),\n            haxby_opcodes::OPCODE_XOR => Ok(Opcode::Xor),\n            haxby_opcodes::OPCODE_BITWISE_AND => Ok(Opcode::BitwiseAnd),\n            haxby_opcodes::OPCODE_BITWISE_OR => Ok(Opcode::BitwiseOr),\n            haxby_opcodes::OPCODE_JUMP_TRUE => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::JumpTrue(b))\n                }),\n            haxby_opcodes::OPCODE_JUMP_FALSE => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::JumpFalse(b))\n                }),\n            haxby_opcodes::OPCODE_JUMP => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| Ok(Opcode::Jump(b))),\n            haxby_opcodes::OPCODE_JUMP_CONDITIONALLY => {\n                let arg0 = match self.read_u16() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let arg1 = match self.read_u16() {\n                    Ok(w) => w,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                Ok(Opcode::JumpConditionally(arg0, arg1))\n            }\n            haxby_opcodes::OPCODE_JUMP_IF_ARG_SUPPLIED => {\n                let arg0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let arg1 = match self.read_u16() {\n                    Ok(w) => w,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                Ok(Opcode::JumpIfArgSupplied(arg0, arg1))\n            }\n            haxby_opcodes::OPCODE_CALL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| Ok(Opcode::Call(b))),\n            haxby_opcodes::OPCODE_RETURN => Ok(Opcode::Return),\n            haxby_opcodes::OPCODE_RETURN_UNIT => Ok(Opcode::ReturnUnit),\n            haxby_opcodes::OPCODE_TRY_ENTER => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::TryEnter(b))\n                }),\n            haxby_opcodes::OPCODE_TRY_EXIT => Ok(Opcode::TryExit),\n            haxby_opcodes::OPCODE_THROW => Ok(Opcode::Throw),\n            haxby_opcodes::OPCODE_BUILD_LIST => self\n                .read_u32()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::BuildList(b))\n                }),\n            haxby_opcodes::OPCODE_BUILD_FUNCTION => Ok(Opcode::BuildFunction),\n            haxby_opcodes::OPCODE_STORE_UPLEVEL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::StoreUplevel(b))\n                }),\n            haxby_opcodes::OPCODE_BUILD_STRUCT => Ok(Opcode::BuildStruct),\n            haxby_opcodes::OPCODE_BUILD_ENUM => Ok(Opcode::BuildEnum),\n            haxby_opcodes::OPCODE_BUILD_MIXIN => Ok(Opcode::BuildMixin),\n            haxby_opcodes::OPCODE_BIND_CASE => {\n                let b0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let w1 = match self.read_u16() {\n                    Ok(w) => w,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                Ok(Opcode::BindCase(b0, w1))\n            }\n            haxby_opcodes::OPCODE_BIND_CASE_SYMBOL => {\n                let b0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let w1 = match self.read_u32() {\n                    Ok(w) => w,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                Ok(Opcode::BindCaseSymbol(b0, w1))\n            }\n            haxby_opcodes::OPCODE_INCLUDE_MIXIN => Ok(Opcode::IncludeMixin),\n            haxby_opcodes::OPCODE_NEW_ENUM_VAL => {\n                let b0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let w1 = match self.read_u16() {\n                    Ok(w) => w,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                Ok(Opcode::NewEnumVal(b0, w1))\n            }\n            haxby_opcodes::OPCODE_ENUM_CHECK_IS_CASE => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::EnumCheckIsCase(b))\n                }),\n            haxby_opcodes::OPCODE_NEW_ENUM_VAL_SYMBOL => {\n                let b0 = match self.read_u8() {\n                    Ok(b) => b,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                let w1 = match self.read_u32() {\n                    Ok(w) => w,\n                    Err(_) => {\n                        return Err(DecodeError::InsufficientData);\n                    }\n                };\n                Ok(Opcode::NewEnumValSymbol(b0, w1))\n            }\n            haxby_opcodes::OPCODE_ENUM_CHECK_IS_CASE_SYMBOL => self\n                .read_u32()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::EnumCheckIsCaseSymbol(b))\n                }),\n            haxby_opcodes::OPCODE_ENUM_TRY_EXTRACT_PAYLOAD => Ok(Opcode::EnumTryExtractPayload),\n            haxby_opcodes::OPCODE_TRY_UNWRAP_PROTOCOL => self\n                .read_u8()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::TryUnwrapProtocol(b))\n                }),\n            haxby_opcodes::OPCODE_ISA => Ok(Opcode::Isa),\n            haxby_opcodes::OPCODE_IMPORT => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::Import(b))\n                }),\n            haxby_opcodes::OPCODE_LIFT_MODULE => Ok(Opcode::LiftModule),\n            haxby_opcodes::OPCODE_LOAD_DYLIB => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::LoadDylib(b))\n                }),\n            haxby_opcodes::OPCODE_ASSERT => self\n                .read_u16()\n                .map_or(Err(DecodeError::InsufficientData), |b| {\n                    Ok(Opcode::Assert(b))\n                }),\n            haxby_opcodes::OPCODE_HALT => Ok(Opcode::Halt),\n            _ => Err(DecodeError::UnknownOpcode(next)),\n        }\n    }\n\n    pub fn len(&self) -> usize {\n        self.data.len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.data.is_empty()\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/bc_writer.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::Opcode;\n\n#[derive(Default)]\npub(crate) struct BytecodeWriter {\n    data: Vec<u8>,\n}\n\nimpl BytecodeWriter {\n    fn write_u8(&mut self, val: u8) -> &mut Self {\n        self.data.push(val);\n        self\n    }\n\n    fn write_u16(&mut self, val: u16) -> &mut Self {\n        let bytes = val.to_le_bytes();\n        self.write_u8(bytes[0]).write_u8(bytes[1])\n    }\n\n    fn write_u32(&mut self, val: u32) -> &mut Self {\n        let bytes = val.to_le_bytes();\n        self.write_u8(bytes[0])\n            .write_u8(bytes[1])\n            .write_u8(bytes[2])\n            .write_u8(bytes[3])\n    }\n\n    pub(crate) fn write_opcode(&mut self, op: &Opcode) -> &mut Self {\n        match op {\n            Opcode::Nop => self.write_u8(haxby_opcodes::OPCODE_NOP),\n            Opcode::Push(n) => self.write_u8(haxby_opcodes::OPCODE_PUSH).write_u16(*n),\n            Opcode::Push0 => self.write_u8(haxby_opcodes::OPCODE_PUSH_0),\n            Opcode::Push1 => self.write_u8(haxby_opcodes::OPCODE_PUSH_1),\n            Opcode::PushTrue => self.write_u8(haxby_opcodes::OPCODE_PUSH_TRUE),\n            Opcode::PushFalse => self.write_u8(haxby_opcodes::OPCODE_PUSH_FALSE),\n            Opcode::PushBuiltinTy(n) => self\n                .write_u8(haxby_opcodes::OPCODE_PUSH_BUILTIN_TYPE)\n                .write_u8(n.to_u8()),\n            Opcode::PushRuntimeValue(n) => self\n                .write_u8(haxby_opcodes::OPCODE_PUSH_RUNTIME_VALUE)\n                .write_u8(n.to_u8()),\n            Opcode::Pop => self.write_u8(haxby_opcodes::OPCODE_POP),\n            Opcode::Dup => self.write_u8(haxby_opcodes::OPCODE_DUP),\n            Opcode::Swap => self.write_u8(haxby_opcodes::OPCODE_SWAP),\n            Opcode::Copy(n) => self.write_u8(haxby_opcodes::OPCODE_COPY).write_u8(*n),\n            Opcode::Add => self.write_u8(haxby_opcodes::OPCODE_ADD),\n            Opcode::Sub => self.write_u8(haxby_opcodes::OPCODE_SUB),\n            Opcode::Mul => self.write_u8(haxby_opcodes::OPCODE_MUL),\n            Opcode::Div => self.write_u8(haxby_opcodes::OPCODE_DIV),\n            Opcode::Rem => self.write_u8(haxby_opcodes::OPCODE_REM),\n            Opcode::Neg => self.write_u8(haxby_opcodes::OPCODE_NEG),\n            Opcode::ShiftLeft => self.write_u8(haxby_opcodes::OPCODE_SHL),\n            Opcode::ShiftRight => self.write_u8(haxby_opcodes::OPCODE_SHR),\n            Opcode::Not => self.write_u8(haxby_opcodes::OPCODE_NOT),\n            Opcode::Equal => self.write_u8(haxby_opcodes::OPCODE_EQ),\n            Opcode::ReadLocal(n) => self.write_u8(haxby_opcodes::OPCODE_READ_LOCAL).write_u8(*n),\n            Opcode::WriteLocal(n) => self\n                .write_u8(haxby_opcodes::OPCODE_WRITE_LOCAL)\n                .write_u8(*n),\n            Opcode::TypedefLocal(n) => self\n                .write_u8(haxby_opcodes::OPCODE_TYPEDEF_LOCAL)\n                .write_u8(*n),\n            Opcode::ReadNamed(n) => self\n                .write_u8(haxby_opcodes::OPCODE_READ_NAMED)\n                .write_u16(*n),\n            Opcode::WriteNamed(n) => self\n                .write_u8(haxby_opcodes::OPCODE_WRITE_NAMED)\n                .write_u16(*n),\n            Opcode::TypedefNamed(n) => self\n                .write_u8(haxby_opcodes::OPCODE_TYPEDEF_NAMED)\n                .write_u16(*n),\n            Opcode::ReadIndex(n) => self.write_u8(haxby_opcodes::OPCODE_READ_INDEX).write_u8(*n),\n            Opcode::WriteIndex(n) => self\n                .write_u8(haxby_opcodes::OPCODE_WRITE_INDEX)\n                .write_u8(*n),\n            Opcode::ReadAttribute(n) => self\n                .write_u8(haxby_opcodes::OPCODE_READ_ATTRIBUTE)\n                .write_u16(*n),\n            Opcode::WriteAttribute(n) => self\n                .write_u8(haxby_opcodes::OPCODE_WRITE_ATTRIBUTE)\n                .write_u16(*n),\n            Opcode::ReadAttributeSymbol(n) => self\n                .write_u8(haxby_opcodes::OPCODE_READ_ATTRIBUTE_SYMBOL)\n                .write_u32(*n),\n            Opcode::WriteAttributeSymbol(n) => self\n                .write_u8(haxby_opcodes::OPCODE_WRITE_ATTRIBUTE_SYMBOL)\n                .write_u32(*n),\n            Opcode::ReadUplevel(n) => self\n                .write_u8(haxby_opcodes::OPCODE_READ_UPLEVEL)\n                .write_u8(*n),\n            Opcode::LogicalAnd => self.write_u8(haxby_opcodes::OPCODE_LOGICAL_AND),\n            Opcode::LogicalOr => self.write_u8(haxby_opcodes::OPCODE_LOGICAL_OR),\n            Opcode::Xor => self.write_u8(haxby_opcodes::OPCODE_XOR),\n            Opcode::BitwiseAnd => self.write_u8(haxby_opcodes::OPCODE_BITWISE_AND),\n            Opcode::BitwiseOr => self.write_u8(haxby_opcodes::OPCODE_BITWISE_OR),\n            Opcode::GreaterThan => self.write_u8(haxby_opcodes::OPCODE_GT),\n            Opcode::LessThan => self.write_u8(haxby_opcodes::OPCODE_LT),\n            Opcode::GreaterThanEqual => self.write_u8(haxby_opcodes::OPCODE_GTE),\n            Opcode::LessThanEqual => self.write_u8(haxby_opcodes::OPCODE_LTE),\n            Opcode::JumpTrue(n) => self.write_u8(haxby_opcodes::OPCODE_JUMP_TRUE).write_u16(*n),\n            Opcode::JumpFalse(n) => self\n                .write_u8(haxby_opcodes::OPCODE_JUMP_FALSE)\n                .write_u16(*n),\n            Opcode::Jump(n) => self.write_u8(haxby_opcodes::OPCODE_JUMP).write_u16(*n),\n            Opcode::JumpConditionally(t, f) => self\n                .write_u8(haxby_opcodes::OPCODE_JUMP_CONDITIONALLY)\n                .write_u16(*t)\n                .write_u16(*f),\n            Opcode::JumpIfArgSupplied(n, d) => self\n                .write_u8(haxby_opcodes::OPCODE_JUMP_IF_ARG_SUPPLIED)\n                .write_u8(*n)\n                .write_u16(*d),\n            Opcode::Call(n) => self.write_u8(haxby_opcodes::OPCODE_CALL).write_u8(*n),\n            Opcode::Return => self.write_u8(haxby_opcodes::OPCODE_RETURN),\n            Opcode::ReturnUnit => self.write_u8(haxby_opcodes::OPCODE_RETURN_UNIT),\n            Opcode::TryEnter(n) => self.write_u8(haxby_opcodes::OPCODE_TRY_ENTER).write_u16(*n),\n            Opcode::TryExit => self.write_u8(haxby_opcodes::OPCODE_TRY_EXIT),\n            Opcode::Throw => self.write_u8(haxby_opcodes::OPCODE_THROW),\n            Opcode::BuildList(n) => self\n                .write_u8(haxby_opcodes::OPCODE_BUILD_LIST)\n                .write_u32(*n),\n            Opcode::BuildFunction => self.write_u8(haxby_opcodes::OPCODE_BUILD_FUNCTION),\n            Opcode::StoreUplevel(n) => self\n                .write_u8(haxby_opcodes::OPCODE_STORE_UPLEVEL)\n                .write_u8(*n),\n            Opcode::BuildStruct => self.write_u8(haxby_opcodes::OPCODE_BUILD_STRUCT),\n            Opcode::BuildMixin => self.write_u8(haxby_opcodes::OPCODE_BUILD_MIXIN),\n            Opcode::BuildEnum => self.write_u8(haxby_opcodes::OPCODE_BUILD_ENUM),\n            Opcode::BindCase(a, n) => self\n                .write_u8(haxby_opcodes::OPCODE_BIND_CASE)\n                .write_u8(*a)\n                .write_u16(*n),\n            Opcode::BindCaseSymbol(a, n) => self\n                .write_u8(haxby_opcodes::OPCODE_BIND_CASE_SYMBOL)\n                .write_u8(*a)\n                .write_u32(*n),\n            Opcode::IncludeMixin => self.write_u8(haxby_opcodes::OPCODE_INCLUDE_MIXIN),\n            Opcode::NewEnumVal(a, n) => self\n                .write_u8(haxby_opcodes::OPCODE_NEW_ENUM_VAL)\n                .write_u8(*a)\n                .write_u16(*n),\n            Opcode::NewEnumValSymbol(a, n) => self\n                .write_u8(haxby_opcodes::OPCODE_NEW_ENUM_VAL_SYMBOL)\n                .write_u8(*a)\n                .write_u32(*n),\n            Opcode::EnumCheckIsCase(n) => self\n                .write_u8(haxby_opcodes::OPCODE_ENUM_CHECK_IS_CASE)\n                .write_u16(*n),\n            Opcode::EnumCheckIsCaseSymbol(n) => self\n                .write_u8(haxby_opcodes::OPCODE_ENUM_CHECK_IS_CASE_SYMBOL)\n                .write_u32(*n),\n            Opcode::EnumTryExtractPayload => {\n                self.write_u8(haxby_opcodes::OPCODE_ENUM_TRY_EXTRACT_PAYLOAD)\n            }\n            Opcode::TryUnwrapProtocol(n) => self\n                .write_u8(haxby_opcodes::OPCODE_TRY_UNWRAP_PROTOCOL)\n                .write_u8(*n),\n            Opcode::Isa => self.write_u8(haxby_opcodes::OPCODE_ISA),\n            Opcode::Import(n) => self.write_u8(haxby_opcodes::OPCODE_IMPORT).write_u16(*n),\n            Opcode::LiftModule => self.write_u8(haxby_opcodes::OPCODE_LIFT_MODULE),\n            Opcode::LoadDylib(n) => self\n                .write_u8(haxby_opcodes::OPCODE_LOAD_DYLIB)\n                .write_u16(*n),\n            Opcode::Assert(n) => self.write_u8(haxby_opcodes::OPCODE_ASSERT).write_u16(*n),\n            Opcode::Halt => self.write_u8(haxby_opcodes::OPCODE_HALT),\n        }\n    }\n\n    pub(crate) fn get_data(&self) -> Vec<u8> {\n        self.data.clone()\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/builder/block.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::{cell::RefCell, collections::HashSet, rc::Rc};\n\nuse aria_parser::ast::SourcePointer;\n\nuse crate::{\n    bc_writer::BytecodeWriter,\n    builder::{compiler_opcodes::CompilerOpcode, func::FunctionBuilder},\n    constant_value::ConstantValues,\n    line_table::LineTable,\n};\n\npub(crate) struct BasicBlockEntry {\n    pub op: CompilerOpcode,\n    pub src: Option<SourcePointer>,\n}\n\nimpl BasicBlockEntry {\n    fn to_vm_opcode(&self, parent: &FunctionBuilder) -> haxby_opcodes::Opcode {\n        self.op.to_vm_opcode(parent)\n    }\n}\n\n// TODO: this should really not be visible outside of block.rs\npub(crate) struct BasicBlockImpl {\n    name: String,\n    id: usize,\n    pub(crate) writer: RefCell<Vec<BasicBlockEntry>>,\n}\n\nimpl BasicBlockImpl {\n    pub(crate) fn new(name: &str, id: usize) -> Self {\n        Self {\n            name: name.to_owned(),\n            id,\n            writer: RefCell::new(Default::default()),\n        }\n    }\n}\n\n#[derive(Clone)]\npub struct BasicBlock {\n    pub(crate) imp: Rc<BasicBlockImpl>,\n}\n\nimpl PartialEq for BasicBlock {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for BasicBlock {}\n\n#[derive(Default)]\npub(crate) struct LocalValuesAccess {\n    pub(crate) reads: HashSet<u8>,\n    pub(crate) writes: HashSet<u8>,\n}\n\nimpl LocalValuesAccess {\n    pub(crate) fn calculate_unused_locals(&self) -> HashSet<u8> {\n        self.writes.difference(&self.reads).cloned().collect()\n    }\n}\n\nimpl BasicBlock {\n    pub(crate) fn new(name: &str, id: usize) -> Self {\n        Self {\n            imp: Rc::new(BasicBlockImpl::new(name, id)),\n        }\n    }\n\n    pub fn name(&self) -> &str {\n        &self.imp.name\n    }\n\n    pub fn id(&self) -> usize {\n        self.imp.id\n    }\n\n    #[deprecated(note = \"use write_opcode_and_source_info\")]\n    pub fn write_opcode(&self, op: CompilerOpcode) -> &Self {\n        let bbe = BasicBlockEntry { op, src: None };\n        self.imp.writer.borrow_mut().push(bbe);\n        self\n    }\n\n    pub fn write_opcode_and_source_info(&self, op: CompilerOpcode, src: SourcePointer) -> &Self {\n        let bbe = BasicBlockEntry { op, src: Some(src) };\n        self.imp.writer.borrow_mut().push(bbe);\n        self\n    }\n\n    pub fn len(&self) -> usize {\n        self.imp.writer.borrow().len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.imp.writer.borrow().is_empty()\n    }\n\n    pub fn is_terminal(&self) -> bool {\n        let br = self.imp.writer.borrow();\n        for src_op in br.as_slice() {\n            if src_op.op.is_terminal() {\n                return true;\n            }\n        }\n\n        false\n    }\n\n    #[allow(dead_code)]\n    pub(crate) fn remove_op_at_idx(&self, idx: usize) {\n        self.imp.writer.borrow_mut().remove(idx);\n    }\n\n    fn replace_double_jump(&self) -> bool {\n        let mut any = false;\n\n        let mut br = self.imp.writer.borrow_mut();\n        for i in 0..br.len() {\n            if let CompilerOpcode::Jump(dest) = &br[i].op {\n                let dest = dest.clone();\n                if dest.imp.id == self.imp.id {\n                    continue;\n                }\n                if dest.is_empty() {\n                    continue;\n                }\n                let dest_br = dest.imp.writer.borrow();\n                if let CompilerOpcode::Jump(final_dest) = &dest_br[0].op {\n                    br[i].op = CompilerOpcode::Jump(final_dest.clone());\n                    any = true;\n                }\n            }\n        }\n\n        any\n    }\n\n    fn optimize_true_false(&self, cv: &ConstantValues) {\n        let mut br = self.imp.writer.borrow_mut();\n        for i in 0..br.len() {\n            if let CompilerOpcode::ReadNamed(idx) = &br[i].op\n                && let Some(crate::constant_value::ConstantValue::String(x)) = cv.get(*idx as usize)\n            {\n                if x == \"true\" {\n                    br[i].op = CompilerOpcode::PushTrue;\n                } else if x == \"false\" {\n                    br[i].op = CompilerOpcode::PushFalse;\n                }\n            }\n        }\n    }\n\n    fn optimize_redundant_conditional_jumps(&self) {\n        let mut br = self.imp.writer.borrow_mut();\n        let mut i = 0;\n        while i + 1 < br.len() {\n            match (&br[i].op, &br[i + 1].op) {\n                (CompilerOpcode::PushTrue, CompilerOpcode::JumpTrue(target))\n                | (CompilerOpcode::PushFalse, CompilerOpcode::JumpFalse(target)) => {\n                    br[i].op = CompilerOpcode::Jump(target.clone());\n                    br.remove(i + 1);\n                    continue;\n                }\n                (CompilerOpcode::PushTrue, CompilerOpcode::JumpFalse(_))\n                | (CompilerOpcode::PushFalse, CompilerOpcode::JumpTrue(_)) => {\n                    br[i].op = CompilerOpcode::Nop;\n                    br.remove(i + 1);\n                    continue;\n                }\n                _ => {}\n            }\n\n            i += 1;\n        }\n    }\n\n    fn remove_instructions_after_terminal(&self) {\n        let mut br = self.imp.writer.borrow_mut();\n        for i in 0..br.len() {\n            if br[i].op.is_terminal() {\n                while br.len() != i + 1 {\n                    br.remove(i + 1);\n                }\n                return;\n            }\n        }\n    }\n\n    fn remove_redundant_local_reads(&self) {\n        let mut br = self.imp.writer.borrow_mut();\n        if br.len() < 2 {\n            return;\n        }\n\n        for i in 0..br.len() - 1 {\n            if let CompilerOpcode::ReadLocal(x) = br[i].op {\n                let mut j = i + 1;\n                while j < br.len() {\n                    match br[j].op {\n                        CompilerOpcode::ReadLocal(y) => {\n                            if x != y {\n                                break;\n                            } else {\n                                br[j].op = CompilerOpcode::Dup;\n                            }\n                        }\n                        _ => {\n                            break;\n                        }\n                    }\n                    j += 1;\n                }\n            }\n        }\n    }\n\n    fn remove_redundant_named_reads(&self) {\n        let mut br = self.imp.writer.borrow_mut();\n        if br.len() < 2 {\n            return;\n        }\n\n        for i in 0..br.len() - 1 {\n            if let CompilerOpcode::ReadNamed(x) = br[i].op {\n                let mut j = i + 1;\n                while j < br.len() {\n                    match br[j].op {\n                        CompilerOpcode::ReadNamed(y) => {\n                            if x != y {\n                                break;\n                            } else {\n                                br[j].op = CompilerOpcode::Dup;\n                            }\n                        }\n                        _ => {\n                            break;\n                        }\n                    }\n                    j += 1;\n                }\n            }\n        }\n    }\n\n    fn remove_store_load_sequence(&self) {\n        if self.len() < 2 {\n            return;\n        }\n\n        let mut br = self.imp.writer.borrow_mut();\n\n        for i in 0..br.len() - 1 {\n            if let CompilerOpcode::WriteLocal(x) = br[i].op\n                && let CompilerOpcode::ReadLocal(y) = br[i + 1].op\n                && x == y\n            {\n                br[i].op = CompilerOpcode::Dup;\n                br[i + 1].op = CompilerOpcode::WriteLocal(x);\n            }\n        }\n    }\n\n    fn remove_nop_instructions(&self) {\n        let mut br = self.imp.writer.borrow_mut();\n        br.retain(|x| !matches!(x.op, CompilerOpcode::Nop));\n    }\n\n    fn remove_push_pop_pairs(&self) {\n        if self.len() < 2 {\n            return;\n        }\n\n        let mut br = self.imp.writer.borrow_mut();\n\n        for i in 0..br.len() - 1 {\n            if let (\n                CompilerOpcode::Push0\n                | CompilerOpcode::Push1\n                | CompilerOpcode::PushFalse\n                | CompilerOpcode::PushTrue\n                | CompilerOpcode::Push(_)\n                | CompilerOpcode::PushBuiltinTy(_)\n                | CompilerOpcode::Dup,\n                CompilerOpcode::Pop,\n            ) = (&br[i].op, &br[i + 1].op)\n            {\n                br[i].op = CompilerOpcode::Nop;\n                br[i + 1].op = CompilerOpcode::Nop;\n            }\n        }\n    }\n\n    pub(crate) fn run_optimize_passes(&self, cv: &ConstantValues) {\n        self.optimize_true_false(cv);\n        self.optimize_redundant_conditional_jumps();\n        self.remove_redundant_local_reads();\n        self.remove_redundant_named_reads();\n        self.remove_store_load_sequence();\n        self.remove_instructions_after_terminal();\n        self.remove_nop_instructions();\n        self.remove_push_pop_pairs();\n        self.remove_nop_instructions();\n        while self.replace_double_jump() {}\n    }\n\n    pub(crate) fn drop_unused_locals(&self, values: &HashSet<u8>) {\n        let mut br = self.imp.writer.borrow_mut();\n\n        for i in 0..br.len() {\n            match br[i].op {\n                CompilerOpcode::ReadLocal(x) => {\n                    assert!(!values.contains(&x));\n                }\n                CompilerOpcode::TypedefLocal(x) => {\n                    if values.contains(&x) {\n                        br[i].op = CompilerOpcode::Pop;\n                    }\n                }\n                CompilerOpcode::WriteLocal(x) => {\n                    if values.contains(&x) {\n                        br[i].op = CompilerOpcode::Pop;\n                    }\n                }\n                _ => {}\n            }\n        }\n    }\n\n    pub(crate) fn calculate_locals_access(&self, dest: &mut LocalValuesAccess) {\n        let br = self.imp.writer.borrow();\n        for i in 0..br.len() {\n            match br[i].op {\n                CompilerOpcode::ReadLocal(x) | CompilerOpcode::StoreUplevel(x) => {\n                    dest.reads.insert(x);\n                }\n                CompilerOpcode::WriteLocal(x) => {\n                    dest.writes.insert(x);\n                }\n                CompilerOpcode::TypedefLocal(x) => {\n                    if i > 0 {\n                        if let CompilerOpcode::PushBuiltinTy(t) = br[i - 1].op\n                            && t.is_any()\n                        {\n                            dest.writes.insert(x);\n                        } else {\n                            dest.reads.insert(x);\n                            dest.writes.insert(x);\n                        }\n                    } else {\n                        // this is quite odd, as there would have to be something else defining\n                        // the type of the local on the stack, but just keep going for sake of completeness\n                        dest.writes.insert(x);\n                    }\n                }\n                _ => {}\n            }\n        }\n    }\n\n    pub(crate) fn write(&self, parent: &FunctionBuilder, dest: &mut BytecodeWriter) {\n        let br = self.imp.writer.borrow();\n        for src_op in br.as_slice() {\n            dest.write_opcode(&src_op.to_vm_opcode(parent));\n        }\n    }\n\n    pub(crate) fn write_line_table(&self, offset: u16, line_table: &LineTable) {\n        let mut cur_offset = offset;\n        let br = self.imp.writer.borrow();\n        for src_op in br.as_slice() {\n            if let Some(src) = &src_op.src {\n                line_table.insert(cur_offset, src.clone());\n            }\n            cur_offset += 1;\n        }\n    }\n}\n\nimpl std::fmt::Display for BasicBlock {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let br = self.imp.writer.borrow();\n        writeln!(f, \"BasicBlock {}:\", self.imp.name)?;\n        for src_op in br.as_slice() {\n            writeln!(f, \"  {}\", src_op.op)?;\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/builder/compiler_opcodes.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse enum_as_inner::EnumAsInner;\nuse haxby_opcodes::{\n    BuiltinTypeId, BuiltinValueId, Opcode as VmOpcode, enum_case_attribs::CASE_HAS_PAYLOAD,\n};\n\nuse crate::builder::{block::BasicBlock, func::FunctionBuilder};\n\n#[derive(Clone, EnumAsInner)]\npub enum CompilerOpcode {\n    Nop,\n    Push(u16),\n    Push0,\n    Push1,\n    PushTrue,\n    PushFalse,\n    PushBuiltinTy(BuiltinTypeId),\n    PushRuntimeValue(BuiltinValueId),\n    Pop,\n    Dup,\n    Swap,\n    Copy(u8),\n    Add,\n    Sub,\n    Mul,\n    Div,\n    Rem,\n    Neg,\n    ShiftLeft,\n    ShiftRight,\n    Not,\n    Equal,\n    ReadLocal(u8),\n    WriteLocal(u8),\n    TypedefLocal(u8),\n    ReadNamed(u16),\n    WriteNamed(u16),\n    TypedefNamed(u16),\n    ReadIndex(u8),\n    WriteIndex(u8),\n    ReadAttribute(u16),\n    WriteAttribute(u16),\n    ReadUplevel(u8),\n    LogicalAnd,\n    BitwiseAnd,\n    LogicalOr,\n    BitwiseOr,\n    Xor,\n    GreaterThan,\n    GreaterThanEqual,\n    LessThan,\n    LessThanEqual,\n    JumpTrue(BasicBlock),\n    JumpFalse(BasicBlock),\n    Jump(BasicBlock),\n    JumpConditionally(BasicBlock, BasicBlock),\n    JumpIfArgSupplied(u8, BasicBlock),\n    Call(u8),\n    Return,\n    ReturnUnit,\n    TryEnter(BasicBlock),\n    TryExit,\n    Throw,\n    BuildList(u32),\n    BuildFunction,\n    StoreUplevel(u8),\n    BuildStruct,\n    BuildEnum,\n    BuildMixin,\n    BindCase(u8, u16),\n    IncludeMixin,\n    NewEnumVal(bool, u16),\n    EnumCheckIsCase(u16),\n    EnumTryExtractPayload,\n    TryUnwrapProtocol(u8),\n    Isa,\n    Import(u16),\n    LiftModule,\n    LoadDylib(u16),\n    Assert(u16),\n    Halt,\n}\n\nimpl CompilerOpcode {\n    pub fn is_terminal(&self) -> bool {\n        match self {\n            Self::Nop => false,\n            Self::Push(_) => false,\n            Self::Push0 => false,\n            Self::Push1 => false,\n            Self::PushTrue => false,\n            Self::PushFalse => false,\n            Self::PushBuiltinTy(_) => false,\n            Self::PushRuntimeValue(_) => false,\n            Self::Pop => false,\n            Self::Dup => false,\n            Self::Swap => false,\n            Self::Copy(_) => false,\n            Self::Add => false,\n            Self::Sub => false,\n            Self::Mul => false,\n            Self::Div => false,\n            Self::Rem => false,\n            Self::Neg => false,\n            Self::ShiftLeft => false,\n            Self::ShiftRight => false,\n            Self::Not => false,\n            Self::Equal => false,\n            Self::ReadLocal(_) => false,\n            Self::WriteLocal(_) => false,\n            Self::TypedefLocal(_) => false,\n            Self::ReadNamed(_) => false,\n            Self::WriteNamed(_) => false,\n            Self::TypedefNamed(_) => false,\n            Self::ReadIndex(_) => false,\n            Self::WriteIndex(_) => false,\n            Self::ReadAttribute(_) => false,\n            Self::WriteAttribute(_) => false,\n            Self::ReadUplevel(_) => false,\n            Self::LogicalAnd => false,\n            Self::LogicalOr => false,\n            Self::Xor => false,\n            Self::BitwiseAnd => false,\n            Self::BitwiseOr => false,\n            Self::LessThan => false,\n            Self::GreaterThan => false,\n            Self::LessThanEqual => false,\n            Self::GreaterThanEqual => false,\n            Self::JumpTrue(_) => false,\n            Self::JumpFalse(_) => false,\n            Self::Jump(_) => true,\n            Self::JumpConditionally(..) => true,\n            Self::JumpIfArgSupplied(..) => false,\n            Self::Call(_) => false,\n            Self::Return => true,\n            Self::ReturnUnit => true,\n            Self::TryEnter(_) => false,\n            Self::TryExit => false,\n            Self::Throw => true,\n            Self::BuildList(_) => false,\n            Self::BuildFunction => false,\n            Self::StoreUplevel(_) => false,\n            Self::BuildStruct => false,\n            Self::BuildEnum => false,\n            Self::BuildMixin => false,\n            Self::BindCase(..) => false,\n            Self::IncludeMixin => false,\n            Self::NewEnumVal(..) => false,\n            Self::EnumCheckIsCase(_) => false,\n            Self::EnumTryExtractPayload => false,\n            Self::TryUnwrapProtocol(_) => false,\n            Self::Isa => false,\n            Self::Import(_) => false,\n            Self::LiftModule => false,\n            Self::LoadDylib(_) => false,\n            Self::Assert(_) => false,\n            Self::Halt => true,\n        }\n    }\n\n    pub fn is_jump_instruction(&self) -> Vec<BasicBlock> {\n        match self {\n            Self::TryEnter(dst)\n            | Self::JumpIfArgSupplied(_, dst)\n            | Self::Jump(dst)\n            | Self::JumpTrue(dst)\n            | Self::JumpFalse(dst) => vec![dst.clone()],\n            Self::JumpConditionally(t, f) => vec![t.clone(), f.clone()],\n            _ => vec![],\n        }\n    }\n\n    pub fn to_vm_opcode(&self, parent: &FunctionBuilder) -> VmOpcode {\n        match self {\n            Self::Nop => VmOpcode::Nop,\n            Self::Push(v) => VmOpcode::Push(*v),\n            Self::Push0 => VmOpcode::Push0,\n            Self::Push1 => VmOpcode::Push1,\n            Self::PushTrue => VmOpcode::PushTrue,\n            Self::PushFalse => VmOpcode::PushFalse,\n            Self::PushBuiltinTy(n) => VmOpcode::PushBuiltinTy(*n),\n            Self::PushRuntimeValue(n) => VmOpcode::PushRuntimeValue(*n),\n            Self::Pop => VmOpcode::Pop,\n            Self::Dup => VmOpcode::Dup,\n            Self::Swap => VmOpcode::Swap,\n            Self::Copy(n) => VmOpcode::Copy(*n),\n            Self::Add => VmOpcode::Add,\n            Self::Sub => VmOpcode::Sub,\n            Self::Mul => VmOpcode::Mul,\n            Self::Div => VmOpcode::Div,\n            Self::Rem => VmOpcode::Rem,\n            Self::Neg => VmOpcode::Neg,\n            Self::ShiftLeft => VmOpcode::ShiftLeft,\n            Self::ShiftRight => VmOpcode::ShiftRight,\n            Self::Not => VmOpcode::Not,\n            Self::Equal => VmOpcode::Equal,\n            Self::ReadLocal(n) => VmOpcode::ReadLocal(*n),\n            Self::WriteLocal(n) => VmOpcode::WriteLocal(*n),\n            Self::TypedefLocal(n) => VmOpcode::TypedefLocal(*n),\n            Self::ReadNamed(n) => VmOpcode::ReadNamed(*n),\n            Self::WriteNamed(n) => VmOpcode::WriteNamed(*n),\n            Self::TypedefNamed(n) => VmOpcode::TypedefNamed(*n),\n            Self::ReadIndex(n) => VmOpcode::ReadIndex(*n),\n            Self::WriteIndex(n) => VmOpcode::WriteIndex(*n),\n            Self::ReadAttribute(n) => VmOpcode::ReadAttribute(*n),\n            Self::WriteAttribute(n) => VmOpcode::WriteAttribute(*n),\n            Self::ReadUplevel(n) => VmOpcode::ReadUplevel(*n),\n            Self::LogicalAnd => VmOpcode::LogicalAnd,\n            Self::LogicalOr => VmOpcode::LogicalOr,\n            Self::Xor => VmOpcode::Xor,\n            Self::BitwiseAnd => VmOpcode::BitwiseAnd,\n            Self::BitwiseOr => VmOpcode::BitwiseOr,\n            Self::GreaterThan => VmOpcode::GreaterThan,\n            Self::LessThan => VmOpcode::LessThan,\n            Self::GreaterThanEqual => VmOpcode::GreaterThanEqual,\n            Self::LessThanEqual => VmOpcode::LessThanEqual,\n            Self::JumpTrue(dst) => {\n                let offset = parent\n                    .position_of_block_instructions(dst)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", dst.name()));\n                VmOpcode::JumpTrue(offset)\n            }\n            Self::JumpFalse(dst) => {\n                let offset = parent\n                    .position_of_block_instructions(dst)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", dst.name()));\n                VmOpcode::JumpFalse(offset)\n            }\n            Self::Jump(dst) => {\n                let offset = parent\n                    .position_of_block_instructions(dst)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", dst.name()));\n                VmOpcode::Jump(offset)\n            }\n            Self::JumpConditionally(t, f) => {\n                let t_offset = parent\n                    .position_of_block_instructions(t)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", t.name()));\n                let f_offset = parent\n                    .position_of_block_instructions(f)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", f.name()));\n                VmOpcode::JumpConditionally(t_offset, f_offset)\n            }\n            Self::JumpIfArgSupplied(arg, dst) => {\n                let offset = parent\n                    .position_of_block_instructions(dst)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", dst.name()));\n                VmOpcode::JumpIfArgSupplied(*arg, offset)\n            }\n            Self::Call(n) => VmOpcode::Call(*n),\n            Self::Return => VmOpcode::Return,\n            Self::ReturnUnit => VmOpcode::ReturnUnit,\n            Self::TryEnter(dst) => {\n                let offset = parent\n                    .position_of_block_instructions(dst)\n                    .unwrap_or_else(|| panic!(\"invalid block {}\", dst.name()));\n                VmOpcode::TryEnter(offset)\n            }\n            Self::TryExit => VmOpcode::TryExit,\n            Self::Throw => VmOpcode::Throw,\n            Self::BuildList(v) => VmOpcode::BuildList(*v),\n            Self::BuildFunction => VmOpcode::BuildFunction,\n            Self::StoreUplevel(a) => VmOpcode::StoreUplevel(*a),\n            Self::BuildStruct => VmOpcode::BuildStruct,\n            Self::BuildEnum => VmOpcode::BuildEnum,\n            Self::BuildMixin => VmOpcode::BuildMixin,\n            Self::BindCase(x, y) => VmOpcode::BindCase(*x, *y),\n            Self::IncludeMixin => VmOpcode::IncludeMixin,\n            Self::NewEnumVal(v, n) => {\n                VmOpcode::NewEnumVal(if *v { CASE_HAS_PAYLOAD } else { 0 }, *n)\n            }\n            Self::EnumCheckIsCase(v) => VmOpcode::EnumCheckIsCase(*v),\n            Self::EnumTryExtractPayload => VmOpcode::EnumTryExtractPayload,\n            Self::TryUnwrapProtocol(v) => VmOpcode::TryUnwrapProtocol(*v),\n            Self::Isa => VmOpcode::Isa,\n            Self::Import(v) => VmOpcode::Import(*v),\n            Self::LiftModule => VmOpcode::LiftModule,\n            Self::LoadDylib(n) => VmOpcode::LoadDylib(*n),\n            Self::Assert(v) => VmOpcode::Assert(*v),\n            Self::Halt => VmOpcode::Halt,\n        }\n    }\n}\n\nimpl std::fmt::Display for CompilerOpcode {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        use CompilerOpcode::*;\n        match self {\n            Nop => write!(f, \"Nop\"),\n            Push(v) => write!(f, \"Push({})\", v),\n            Push0 => write!(f, \"Push0\"),\n            Push1 => write!(f, \"Push1\"),\n            PushTrue => write!(f, \"PushTrue\"),\n            PushFalse => write!(f, \"PushFalse\"),\n            PushBuiltinTy(n) => write!(f, \"PushBuiltinTy({})\", n.name()),\n            PushRuntimeValue(n) => write!(f, \"PushRuntimeValue({})\", n.name()),\n            Pop => write!(f, \"Pop\"),\n            Dup => write!(f, \"Dup\"),\n            Swap => write!(f, \"Swap\"),\n            Copy(n) => write!(f, \"Copy({})\", n),\n            Add => write!(f, \"Add\"),\n            Sub => write!(f, \"Sub\"),\n            Mul => write!(f, \"Mul\"),\n            Div => write!(f, \"Div\"),\n            Rem => write!(f, \"Rem\"),\n            Neg => write!(f, \"Neg\"),\n            ShiftLeft => write!(f, \"ShiftLeft\"),\n            ShiftRight => write!(f, \"ShiftRight\"),\n            Not => write!(f, \"Not\"),\n            Equal => write!(f, \"Equal\"),\n            ReadLocal(n) => write!(f, \"ReadLocal({})\", n),\n            WriteLocal(n) => write!(f, \"WriteLocal({})\", n),\n            TypedefLocal(n) => write!(f, \"TypedefLocal({})\", n),\n            ReadNamed(n) => write!(f, \"ReadNamed({})\", n),\n            WriteNamed(n) => write!(f, \"WriteNamed({})\", n),\n            TypedefNamed(n) => write!(f, \"TypedefNamed({})\", n),\n            ReadIndex(n) => write!(f, \"ReadIndex({})\", n),\n            WriteIndex(n) => write!(f, \"WriteIndex({})\", n),\n            ReadAttribute(n) => write!(f, \"ReadAttribute({})\", n),\n            WriteAttribute(n) => write!(f, \"WriteAttribute({})\", n),\n            ReadUplevel(n) => write!(f, \"ReadUplevel({})\", n),\n            LogicalAnd => write!(f, \"LogicalAnd\"),\n            BitwiseAnd => write!(f, \"BitwiseAnd\"),\n            LogicalOr => write!(f, \"LogicalOr\"),\n            BitwiseOr => write!(f, \"BitwiseOr\"),\n            Xor => write!(f, \"Xor\"),\n            GreaterThan => write!(f, \"GreaterThan\"),\n            GreaterThanEqual => write!(f, \"GreaterThanEqual\"),\n            LessThan => write!(f, \"LessThan\"),\n            LessThanEqual => write!(f, \"LessThanEqual\"),\n            JumpTrue(dst) => write!(f, \"JumpTrue({})\", dst.name()),\n            JumpFalse(dst) => write!(f, \"JumpFalse({})\", dst.name()),\n            Jump(dst) => write!(f, \"Jump({})\", dst.name()),\n            JumpIfArgSupplied(arg, dst) => {\n                write!(f, \"JumpIfArgSupplied({}, {})\", arg, dst.name())\n            }\n            JumpConditionally(tr, fa) => {\n                write!(f, \"JumpConditionally({}, {})\", tr.name(), fa.name())\n            }\n            Call(n) => write!(f, \"Call({})\", n),\n            Return => write!(f, \"Return\"),\n            ReturnUnit => write!(f, \"ReturnUnit\"),\n            TryEnter(dst) => write!(f, \"TryEnter({})\", dst.name()),\n            TryExit => write!(f, \"TryExit\"),\n            Throw => write!(f, \"Throw\"),\n            BuildList(v) => write!(f, \"BuildList({})\", v),\n            BuildFunction => write!(f, \"BuildFunction\"),\n            StoreUplevel(a) => write!(f, \"StoreUplevel({})\", a),\n            BuildStruct => write!(f, \"BuildStruct\"),\n            BuildEnum => write!(f, \"BuildEnum\"),\n            BuildMixin => write!(f, \"BuildMixin\"),\n            BindCase(x, y) => write!(f, \"BindCase({}, {})\", x, y),\n            IncludeMixin => write!(f, \"IncludeMixin\"),\n            NewEnumVal(has_payload, n) => write!(f, \"NewEnumVal({}, {})\", has_payload, n),\n            EnumCheckIsCase(v) => write!(f, \"EnumCheckIsCase({})\", v),\n            EnumTryExtractPayload => write!(f, \"EnumTryExtractPayload\"),\n            TryUnwrapProtocol(v) => write!(f, \"TryUnwrapProtocol({})\", v),\n            Isa => write!(f, \"Isa\"),\n            Import(v) => write!(f, \"Import({})\", v),\n            LiftModule => write!(f, \"LiftModule\"),\n            LoadDylib(n) => write!(f, \"LoadDylib({})\", n),\n            Assert(v) => write!(f, \"Assert({})\", v),\n            Halt => write!(f, \"Halt\"),\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/builder/func.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::collections::HashSet;\n\nuse crate::{\n    CompilationOptions,\n    bc_writer::BytecodeWriter,\n    builder::block::{BasicBlock, LocalValuesAccess},\n    constant_value::ConstantValues,\n    line_table::LineTable,\n};\n\npub struct FunctionBuilder {\n    blocks: Vec<BasicBlock>,\n    names: HashSet<String>,\n    current: BasicBlock,\n    bb_id: usize,\n    line_table: LineTable,\n}\n\nimpl Default for FunctionBuilder {\n    fn default() -> Self {\n        let mut this = Self {\n            blocks: Vec::new(),\n            names: HashSet::new(),\n            current: BasicBlock::new(\"entry\", 0),\n            bb_id: 1,\n            line_table: Default::default(),\n        };\n        this.blocks.push(this.current.clone());\n        this.names.insert(this.current.name().to_owned());\n        this\n    }\n}\n\nimpl FunctionBuilder {\n    pub fn try_get_block(&self, name: &str) -> Option<BasicBlock> {\n        for blk in &self.blocks {\n            if blk.name() == name {\n                return Some(blk.clone());\n            }\n        }\n\n        None\n    }\n\n    pub fn get_block(&self, name: &str) -> BasicBlock {\n        self.try_get_block(name).expect(\"block is missing\")\n    }\n\n    fn uniq_name(&self, name: &str) -> String {\n        let mut name = String::from(name);\n        while self.names.contains(&name) {\n            name += \"_\";\n        }\n\n        name\n    }\n\n    fn make_new_block(&mut self, name: &str) -> BasicBlock {\n        assert!(!self.names.contains(name));\n\n        let blk = BasicBlock::new(name, self.bb_id);\n        self.bb_id += 1;\n        blk\n    }\n\n    pub fn insert_block_after(&mut self, name: &str, target: &BasicBlock) -> BasicBlock {\n        let name = self.uniq_name(name);\n        let blk = self.make_new_block(&name);\n        let mut inserted = false;\n\n        for i in 0..self.blocks.len() {\n            let blk_i = &self.blocks[i];\n            if blk_i.id() == target.id() {\n                if i + 1 >= self.blocks.len() {\n                    self.blocks.push(blk.clone());\n                } else {\n                    self.blocks.insert(i + 1, blk.clone());\n                }\n                inserted = true;\n                break;\n            }\n        }\n\n        if !inserted {\n            self.blocks.push(blk.clone());\n        }\n\n        self.names.insert(name);\n        blk\n    }\n\n    pub fn append_block_at_end(&mut self, name: &str) -> BasicBlock {\n        let name = self.uniq_name(name);\n        let blk = self.make_new_block(&name);\n\n        self.blocks.push(blk.clone());\n        self.names.insert(name);\n        blk\n    }\n\n    pub fn set_current_block(&mut self, blk: BasicBlock) {\n        self.current = blk;\n    }\n\n    pub fn get_current_block(&self) -> BasicBlock {\n        self.current.clone()\n    }\n\n    pub fn position_of_block_instructions(&self, blk: &BasicBlock) -> Option<u16> {\n        let mut count = 0;\n        for next in &self.blocks {\n            if next == blk {\n                return Some(count as u16);\n            } else {\n                count += next.len()\n            }\n        }\n        None\n    }\n\n    fn has_entrypoints(&self, blk: &BasicBlock) -> bool {\n        for src_blk in &self.blocks {\n            let br = src_blk.imp.writer.borrow();\n            for src_op in br.as_slice() {\n                for dst in src_op.op.is_jump_instruction() {\n                    if dst.id() == blk.id() {\n                        return true;\n                    }\n                }\n            }\n        }\n        false\n    }\n\n    fn find_orphaned_blocks(&self) -> HashSet<usize> {\n        let mut orphans = HashSet::<usize>::default();\n\n        for blk in &self.blocks {\n            if blk.id() != 0 {\n                let has_entrypoints = self.has_entrypoints(blk);\n                if !has_entrypoints {\n                    orphans.insert(blk.id());\n                }\n            }\n        }\n\n        orphans\n    }\n\n    fn remove_block_with_id(&mut self, id: usize) -> bool {\n        for i in 0..self.blocks.len() {\n            if self.blocks[i].id() == id {\n                self.blocks.remove(i);\n                return true;\n            }\n        }\n\n        false\n    }\n\n    fn run_optimize_passes(&mut self, cv: &ConstantValues) {\n        let orphans = self.find_orphaned_blocks();\n        for orphan_id in &orphans {\n            assert!(self.remove_block_with_id(*orphan_id));\n        }\n\n        let locals_access = self.calculate_locals_access();\n        let unused_locals = locals_access.calculate_unused_locals();\n\n        for blk in &self.blocks {\n            if !unused_locals.is_empty() {\n                blk.drop_unused_locals(&unused_locals);\n            }\n            blk.run_optimize_passes(cv);\n        }\n    }\n\n    fn calculate_locals_access(&self) -> LocalValuesAccess {\n        let mut dest = LocalValuesAccess::default();\n\n        for blk in &self.blocks {\n            blk.calculate_locals_access(&mut dest);\n        }\n\n        dest\n    }\n\n    pub fn write(\n        &mut self,\n        cv: &ConstantValues,\n        options: &CompilationOptions,\n    ) -> Result<Vec<u8>, crate::do_compile::CompilationErrorReason> {\n        if options.dump_builder {\n            println!(\"(unopt) Intermediate Representation Dump:\\n{}\", self);\n        }\n        if options.optimize {\n            self.run_optimize_passes(cv);\n            if options.dump_builder {\n                println!(\"(opt) Intermediate Representation Dump:\\n{}\", self);\n            }\n        }\n\n        let mut dest = BytecodeWriter::default();\n        for blk in &self.blocks {\n            assert!(blk.is_empty() || blk.is_terminal());\n            blk.write(self, &mut dest);\n        }\n\n        let ret = dest.get_data();\n        if ret.len() >= u16::MAX.into() {\n            Err(crate::do_compile::CompilationErrorReason::FunctionBodyTooLarge)\n        } else {\n            Ok(ret)\n        }\n    }\n\n    pub fn write_line_table(&self) -> &LineTable {\n        for blk in &self.blocks {\n            blk.write_line_table(\n                self.position_of_block_instructions(blk).unwrap(),\n                &self.line_table,\n            );\n        }\n\n        &self.line_table\n    }\n}\n\nimpl std::fmt::Display for FunctionBuilder {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        for blk in &self.blocks {\n            writeln!(f, \"{}\", blk)?;\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/builder/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub mod block;\npub mod compiler_opcodes;\npub mod func;\n"
  },
  {
    "path": "compiler-lib/src/constant_value.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::collections::HashMap;\n\nuse aria_parser::ast::SourcePointer;\nuse enum_as_inner::EnumAsInner;\n\nuse crate::line_table::LineTable;\n\n#[derive(Clone, PartialEq, Eq)]\npub struct CompiledCodeObject {\n    pub name: String,\n    pub attribute: u8,\n    pub body: Vec<u8>,\n    pub required_argc: u8, // arguments that are required to call this function\n    pub default_argc: u8,  // additional arguments that this function can accept\n    pub loc: SourcePointer,\n    pub line_table: LineTable,\n    pub frame_size: u8,\n}\n\n#[derive(Clone, Copy)]\npub struct FpConst(f64);\n\nimpl FpConst {\n    fn to_int(self) -> i64 {\n        unsafe { std::mem::transmute(self) }\n    }\n    pub fn raw_value(&self) -> f64 {\n        self.0\n    }\n}\nimpl PartialEq for FpConst {\n    fn eq(&self, other: &Self) -> bool {\n        self.to_int() == other.to_int()\n    }\n}\nimpl Eq for FpConst {}\nimpl std::hash::Hash for FpConst {\n    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {\n        self.to_int().hash(state)\n    }\n}\nimpl From<f64> for FpConst {\n    fn from(value: f64) -> Self {\n        Self(value)\n    }\n}\n\n// ignore the line table and only hash on function code\nimpl std::hash::Hash for CompiledCodeObject {\n    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {\n        self.body.hash(state);\n    }\n}\n\n#[derive(EnumAsInner, Clone, PartialEq, Eq, Hash)]\npub enum ConstantValue {\n    Integer(i64),\n    String(String),\n    Float(FpConst),\n    CompiledCodeObject(CompiledCodeObject),\n}\n\nimpl std::fmt::Display for ConstantValue {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Integer(arg0) => write!(f, \"int:{}\", *arg0),\n            Self::Float(arg0) => write!(f, \"fp:{}\", arg0.0),\n            Self::String(arg0) => write!(f, \"str:\\\"{}\\\"\", *arg0),\n            Self::CompiledCodeObject(_) => write!(f, \"compiled-code-object\"),\n        }\n    }\n}\n\n#[derive(Default)]\npub struct ConstantValues {\n    pub(crate) values: Vec<ConstantValue>,\n    uniq: HashMap<ConstantValue, usize>,\n}\n\npub enum ConstantValuesError {\n    OutOfSpace,\n}\n\nimpl ConstantValues {\n    pub fn insert(&mut self, v: ConstantValue) -> Result<u16, ConstantValuesError> {\n        if let Some(idx) = self.uniq.get(&v) {\n            Ok(*idx as u16)\n        } else {\n            if self.values.len() == (u16::MAX as usize) {\n                return Err(ConstantValuesError::OutOfSpace);\n            }\n\n            let idx = self.values.len();\n            self.uniq.insert(v.clone(), idx);\n            self.values.push(v);\n            Ok(idx as u16)\n        }\n    }\n\n    pub fn get(&self, i: usize) -> Option<ConstantValue> {\n        self.values.get(i).cloned()\n    }\n\n    pub fn len(&self) -> usize {\n        self.values.len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.values.is_empty()\n    }\n\n    pub fn values(&self) -> std::slice::Iter<'_, ConstantValue> {\n        self.values.iter()\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{collections::HashSet, fmt::Display, path::PathBuf};\n\nuse aria_parser::ast::{\n    ArgumentDecl, ArgumentList, AssertStatement, CodeBlock, DeclarationId, ElsePiece, EnumCaseDecl,\n    EnumDecl, EnumDeclEntry, Expression, FunctionBody, Identifier, MatchPattern,\n    MatchPatternEnumCase, MatchRule, MatchStatement, MethodAccess, MethodDecl, MixinIncludeDecl,\n    OperatorDecl, ParsedModule, ReturnStatement, SourceBuffer, SourcePointer, Statement,\n    StringLiteral, StructDecl, StructEntry, ValDeclStatement, prettyprint::PrettyPrintable,\n    source_to_ast,\n};\nuse haxby_opcodes::BuiltinTypeId;\nuse thiserror::Error;\n\nuse crate::{\n    CompilationOptions,\n    builder::{block::BasicBlock, compiler_opcodes::CompilerOpcode, func::FunctionBuilder},\n    constant_value::{ConstantValue, ConstantValuesError},\n    module::CompiledModule,\n    scope::{CompilationScope, ScopeError, ScopeErrorReason},\n};\n\n#[derive(Debug, Error)]\npub enum CompilationErrorReason {\n    #[error(\"identifier is reserved: '{0}'\")]\n    ReservedIdentifier(String),\n    #[error(\"no such identifier: '{0}'\")]\n    NoSuchIdentifier(String),\n    #[error(\"function body is larger than allowed\")]\n    FunctionBodyTooLarge,\n    #[error(\"list length is out of bounds\")]\n    ListTooLarge,\n    #[error(\"attempt to modify a read-only value\")]\n    ReadOnlyValue,\n    #[error(\"{0} is not a valid literal\")]\n    InvalidLiteral(String),\n    #[error(\"{0} is not a valid operator\")]\n    InvalidOperator(String),\n    #[error(\"{0} cannot be reversed\")]\n    IrreversibleOperator(String),\n    #[error(\"operator {0} accepts {1} arguments, but {2} were declared\")]\n    OperatorArityMismatch(String, OperatorArity, usize),\n    #[error(\"attempt to read a write-only value\")]\n    WriteOnlyValue,\n    #[error(\"parser error: {0}\")]\n    ParserError(String),\n    #[error(\"module contains too many constant values\")]\n    TooManyConstants,\n    #[error(\"function accepts too many arguments\")]\n    TooManyArguments,\n    #[error(\"argument without a default value follows argument with default value\")]\n    DefaultArgsMustTrail,\n    #[error(\"flow control statement not permitted in current context\")]\n    FlowControlNotAllowed,\n    #[error(\"argument name '{0}' is already defined for this function\")]\n    DuplicateArgumentName(String),\n    #[error(\"struct members do not support type hints\")]\n    NoTypeHintOnStructMember,\n    #[error(\"nested closures are not supported\")]\n    NestedClosureDisallowed,\n    #[error(\"attempted to write to {0} values, but {1} were provided\")]\n    AssignmentArityMismatch(usize, usize),\n}\n\nimpl From<&ScopeErrorReason> for CompilationErrorReason {\n    fn from(value: &ScopeErrorReason) -> Self {\n        match value {\n            ScopeErrorReason::TooManyConstants => CompilationErrorReason::TooManyConstants,\n            ScopeErrorReason::NoSuchIdentifier(s) => {\n                CompilationErrorReason::NoSuchIdentifier(s.clone())\n            }\n            ScopeErrorReason::OverlyDeepClosure => CompilationErrorReason::NestedClosureDisallowed,\n        }\n    }\n}\n\nimpl From<ScopeError> for CompilationError {\n    fn from(value: ScopeError) -> Self {\n        CompilationError {\n            loc: value.loc,\n            reason: CompilationErrorReason::from(&value.reason),\n        }\n    }\n}\n\nimpl From<&ConstantValuesError> for CompilationErrorReason {\n    fn from(value: &ConstantValuesError) -> Self {\n        match value {\n            ConstantValuesError::OutOfSpace => CompilationErrorReason::TooManyConstants,\n        }\n    }\n}\n\npub struct CompilationError {\n    pub loc: SourcePointer,\n    pub reason: CompilationErrorReason,\n}\n\nimpl std::fmt::Display for CompilationError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"at {}, error occurred: {}\", self.loc, self.reason)\n    }\n}\n\nimpl std::fmt::Debug for CompilationError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"at {}, error occurred: {}\", self.loc, self.reason)\n    }\n}\n\npub type CompilationResult<T = (), E = CompilationError> = Result<T, E>;\n\n#[derive(Default)]\nstruct ControlFlowTargets {\n    break_dest: Option<BasicBlock>,\n    continue_dest: Option<BasicBlock>,\n}\n\nstruct CompileParams<'a> {\n    module: &'a mut CompiledModule,\n    scope: &'a CompilationScope,\n    writer: &'a mut FunctionBuilder,\n    cflow: &'a ControlFlowTargets,\n    options: &'a CompilationOptions,\n}\n\ntrait CompileNode<'a, T = (), E = CompilationError> {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult<T, E>;\n\n    fn insert_const_or_fail(\n        &self,\n        params: &mut CompileParams,\n        ct: ConstantValue,\n        loc: &SourcePointer,\n    ) -> CompilationResult<u16> {\n        match params.module.constants.insert(ct) {\n            Ok(idx) => Ok(idx),\n            Err(_) => Err(CompilationError {\n                loc: loc.clone(),\n                reason: CompilationErrorReason::TooManyConstants,\n            }),\n        }\n    }\n\n    fn return_unit_value(\n        &self,\n        params: &mut CompileParams,\n        loc: &SourcePointer,\n    ) -> CompilationResult {\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::ReturnUnit, loc.clone());\n\n        Ok(())\n    }\n}\n\nmod nodes;\nmod postfix;\n\nfn ensure_arg_list_is_correct(args: &ArgumentList) -> CompilationResult {\n    ensure_unique_arg_names(args)?;\n    ensure_default_args_trailing(args)?;\n    Ok(())\n}\n\nfn ensure_unique_arg_names(args: &ArgumentList) -> CompilationResult {\n    let mut arg_set = HashSet::new();\n    for arg in &args.names {\n        if arg_set.contains(arg.name()) {\n            return Err(CompilationError {\n                loc: arg.loc.clone(),\n                reason: CompilationErrorReason::DuplicateArgumentName(arg.name().to_owned()),\n            });\n        } else {\n            arg_set.insert(arg.name().to_owned());\n        }\n    }\n\n    Ok(())\n}\n\nfn ensure_default_args_trailing(args: &ArgumentList) -> CompilationResult {\n    let mut found_default = false;\n    for arg in &args.names {\n        if arg.deft.is_some() {\n            found_default = true;\n        } else if found_default {\n            return Err(CompilationError {\n                loc: arg.loc.clone(),\n                reason: CompilationErrorReason::DefaultArgsMustTrail,\n            });\n        }\n    }\n\n    Ok(())\n}\n\nfn emit_arg_at_target(\n    arg: &ArgumentDecl,\n    idx: u8,\n    params: &mut CompileParams,\n) -> CompilationResult {\n    if let Some(deft_expr) = arg.deft.as_ref() {\n        let block = params\n            .writer\n            .append_block_at_end(&format!(\"supplied_arg_{idx}\"));\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::JumpIfArgSupplied(idx, block.clone()),\n                arg.loc.clone(),\n            );\n        deft_expr.do_compile(params)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Jump(block.clone()), arg.loc.clone());\n        params.writer.set_current_block(block);\n    }\n    if let Some(ty) = arg.type_info() {\n        ty.do_compile(params)?;\n    } else {\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::PushBuiltinTy(BuiltinTypeId::Any),\n                arg.loc.clone(),\n            );\n    }\n    params.scope.emit_typed_define(\n        arg.name(),\n        &mut params.module.constants,\n        params.writer.get_current_block(),\n        arg.loc.clone(),\n    )?;\n    params.scope.emit_write(\n        arg.name(),\n        &mut params.module.constants,\n        params.writer.get_current_block(),\n        arg.loc.clone(),\n    )?;\n\n    Ok(())\n}\n\n#[allow(dead_code)]\nstruct ArgumentCountInfo {\n    user_args: u8,\n    required_args: u8,\n    default_args: u8,\n    varargs: bool,\n}\n\nfn emit_args_at_target(\n    prefix_args: &[ArgumentDecl],\n    args: &ArgumentList,\n    suffix_args: &[ArgumentDecl],\n    params: &mut CompileParams,\n) -> CompilationResult<ArgumentCountInfo> {\n    ensure_arg_list_is_correct(args)?;\n\n    let total_args = prefix_args.len() + args.names.len() + suffix_args.len();\n    if total_args > u8::MAX.into() {\n        return Err(CompilationError {\n            loc: args.loc.clone(),\n            reason: CompilationErrorReason::TooManyArguments,\n        });\n    }\n\n    let mut argc_info = ArgumentCountInfo {\n        user_args: args.len() as u8,\n        required_args: 0,\n        default_args: 0,\n        varargs: args.vararg,\n    };\n\n    let mut arg_idx: u8 = 0;\n\n    for arg in prefix_args {\n        emit_arg_at_target(arg, arg_idx, params)?;\n        argc_info.required_args += 1;\n        arg_idx += 1;\n    }\n\n    for arg in &args.names {\n        emit_arg_at_target(arg, arg_idx, params)?;\n        if arg.deft.is_some() {\n            argc_info.default_args += 1;\n        } else {\n            argc_info.required_args += 1;\n        }\n        arg_idx += 1;\n    }\n\n    for arg in suffix_args {\n        emit_arg_at_target(arg, arg_idx, params)?;\n        argc_info.required_args += 1;\n        arg_idx += 1;\n    }\n\n    if args.vararg {\n        params.scope.emit_untyped_define(\n            \"varargs\",\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            args.loc.clone(),\n        )?;\n    }\n    Ok(argc_info)\n}\n\n// assume your parent struct is on the stack\nfn emit_type_mixin_include_decl_compile(\n    mi: &MixinIncludeDecl,\n    params: &mut CompileParams,\n) -> CompilationResult {\n    mi.what.do_compile(params)?;\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::IncludeMixin, mi.loc.clone());\n    Ok(())\n}\n\n// assume your parent struct is on the stack\nfn emit_method_decl_compile(md: &MethodDecl, params: &mut CompileParams) -> CompilationResult {\n    md.do_compile(params)?;\n\n    let name_idx = md.insert_const_or_fail(\n        params,\n        ConstantValue::String(md.name.value.clone()),\n        &md.loc,\n    )?;\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::BuildFunction, md.loc.clone())\n        .write_opcode_and_source_info(CompilerOpcode::WriteAttribute(name_idx), md.loc.clone());\n\n    Ok(())\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum OperatorArity {\n    Exactly(usize),\n    AtLeast(usize),\n}\n\nimpl OperatorArity {\n    fn unary() -> Self {\n        OperatorArity::Exactly(1)\n    }\n\n    fn any() -> Self {\n        OperatorArity::AtLeast(0)\n    }\n\n    fn is_acceptable(&self, arg_count: usize) -> bool {\n        match self {\n            OperatorArity::Exactly(n) => *n == arg_count,\n            OperatorArity::AtLeast(n) => arg_count >= *n,\n        }\n    }\n}\n\nimpl Display for OperatorArity {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            OperatorArity::Exactly(n) => write!(f, \"exactly {n}\"),\n            OperatorArity::AtLeast(n) => write!(f, \"at least {n}\"),\n        }\n    }\n}\n\nstruct OperatorInfo {\n    arity: OperatorArity, // number of arguments (minus the receiver this)\n    direct_name: &'static str,\n    reverse_name: &'static str,\n}\n\nlazy_static::lazy_static! {\n    static ref OPERATOR_INFO: std::collections::HashMap<&'static str, OperatorInfo> = {\n        let mut map = std::collections::HashMap::new();\n\n        map.insert(\n            \"+\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"add\",\n                reverse_name: \"radd\",\n            },\n        );\n\n        map.insert(\n            \"-\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"sub\",\n                reverse_name: \"rsub\",\n            },\n        );\n\n        map.insert(\n            \"*\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"mul\",\n                reverse_name: \"rmul\",\n            },\n        );\n\n        map.insert(\n            \"/\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"div\",\n                reverse_name: \"rdiv\",\n            },\n        );\n\n        map.insert(\n            \"%\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"rem\",\n                reverse_name: \"rrem\",\n            },\n        );\n\n        map.insert(\n            \"<<\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"lshift\",\n                reverse_name: \"rlshift\",\n            },\n        );\n\n        map.insert(\n            \">>\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"rshift\",\n                reverse_name: \"rrshift\",\n            },\n        );\n\n        map.insert(\"==\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"equals\",\n                reverse_name: \"\",\n            },\n        );\n\n        map.insert(\"<\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"lt\",\n                reverse_name: \"gt\",\n            },\n        );\n\n        map.insert(\">\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"gt\",\n                reverse_name: \"lt\",\n            },\n        );\n\n        map.insert(\"<=\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"lteq\",\n                reverse_name: \"gteq\",\n            },\n        );\n\n        map.insert(\">=\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"gteq\",\n                reverse_name: \"lteq\",\n            },\n        );\n\n        map.insert(\"&\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"bwand\",\n                reverse_name: \"rbwand\",\n            },\n        );\n\n        map.insert(\"|\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"bwor\",\n                reverse_name: \"rbwor\",\n            },\n        );\n\n        map.insert(\"^\",\n            OperatorInfo {\n                arity: OperatorArity::unary(),\n                direct_name: \"xor\",\n                reverse_name: \"rxor\",\n            },\n        );\n\n        map.insert(\"u-\",\n            OperatorInfo {\n                arity: OperatorArity::Exactly(0),\n                direct_name: \"neg\",\n                reverse_name: \"\",\n            },\n        );\n\n        map.insert(\"()\",\n            OperatorInfo {\n                arity: OperatorArity::any(),\n                direct_name: \"call\",\n                reverse_name: \"\",\n            },\n        );\n\n        map.insert(\"[]\",\n            OperatorInfo {\n                arity: OperatorArity::any(),\n                direct_name: \"read_index\",\n                reverse_name: \"\",\n            },\n        );\n\n        map.insert(\"[]=\",\n            OperatorInfo {\n                arity: OperatorArity::AtLeast(1),\n                direct_name: \"write_index\",\n                reverse_name: \"\",\n            },\n        );\n\n        map\n    };\n}\n\n// assume your parent struct is on the stack\nfn emit_operator_decl_compile(op: &OperatorDecl, params: &mut CompileParams) -> CompilationResult {\n    let op_symbol = op\n        .symbol\n        .prettyprint(\n            aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator::default(),\n        )\n        .value();\n\n    let op_info = match OPERATOR_INFO.get(op_symbol.as_str()) {\n        Some(info) => info,\n        None => {\n            return Err(CompilationError {\n                loc: op.loc.clone(),\n                reason: CompilationErrorReason::InvalidOperator(op_symbol),\n            });\n        }\n    };\n\n    if !op_info.arity.is_acceptable(op.args.len()) {\n        return Err(CompilationError {\n            loc: op.loc.clone(),\n            reason: CompilationErrorReason::OperatorArityMismatch(\n                op_symbol,\n                op_info.arity,\n                op.args.len(),\n            ),\n        });\n    }\n\n    if op.reverse && op_info.reverse_name.is_empty() {\n        return Err(CompilationError {\n            loc: op.loc.clone(),\n            reason: CompilationErrorReason::IrreversibleOperator(op_symbol),\n        });\n    }\n\n    let op_fn_name = format!(\n        \"_op_impl_{}\",\n        if op.reverse {\n            op_info.reverse_name\n        } else {\n            op_info.direct_name\n        }\n    );\n\n    let md = MethodDecl {\n        loc: op.loc.clone(),\n        access: MethodAccess::Instance,\n        name: Identifier {\n            loc: op.loc.clone(),\n            value: op_fn_name,\n        },\n        args: op.args.clone(),\n        body: op.body.clone(),\n    };\n\n    emit_method_decl_compile(&md, params)\n}\n\n// assume your parent struct is on the stack\nfn emit_type_val_decl_compile(\n    vd: &ValDeclStatement,\n    params: &mut CompileParams,\n) -> CompilationResult {\n    for decl in &vd.decls {\n        if decl.id.ty.is_some() {\n            return Err(CompilationError {\n                loc: vd.loc.clone(),\n                reason: CompilationErrorReason::NoTypeHintOnStructMember,\n            });\n        }\n        decl.val.do_compile(params)?;\n        let name_idx = vd.insert_const_or_fail(\n            params,\n            ConstantValue::String(decl.id.name.value.clone()),\n            &vd.loc,\n        )?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::WriteAttribute(name_idx), vd.loc.clone());\n    }\n    Ok(())\n}\n\n// assume your parent struct is on the stack\nfn emit_type_members_compile(\n    entries: &[StructEntry],\n    params: &mut CompileParams,\n    drop_at_end: bool,\n) -> CompilationResult {\n    for se in entries {\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Dup, se.loc().clone());\n\n        match se {\n            aria_parser::ast::StructEntry::Method(md) => emit_method_decl_compile(md, params)?,\n            aria_parser::ast::StructEntry::Operator(od) => emit_operator_decl_compile(od, params)?,\n            aria_parser::ast::StructEntry::Variable(vd) => emit_type_val_decl_compile(vd, params)?,\n            aria_parser::ast::StructEntry::Struct(sd) => {\n                do_struct_compile(sd, params)?;\n\n                let name_idx = sd.insert_const_or_fail(\n                    params,\n                    ConstantValue::String(sd.name.value.clone()),\n                    &sd.loc,\n                )?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::WriteAttribute(name_idx),\n                        sd.loc.clone(),\n                    );\n            }\n            aria_parser::ast::StructEntry::Enum(ed) => {\n                do_enum_compile(ed, params, |name, params| {\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::Swap, ed.loc.clone());\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::Copy(1), ed.loc.clone());\n\n                    let name_idx = ed.insert_const_or_fail(\n                        params,\n                        ConstantValue::String(name.to_owned()),\n                        &ed.loc,\n                    )?;\n\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::WriteAttribute(name_idx),\n                            ed.loc.clone(),\n                        );\n                    Ok(())\n                })?;\n            }\n            aria_parser::ast::StructEntry::MixinInclude(mi) => {\n                emit_type_mixin_include_decl_compile(mi, params)?\n            }\n        }\n    }\n\n    if drop_at_end {\n        // remove the last leftover struct\n        #[allow(deprecated)] // no entry to ascribe this write to\n        params\n            .writer\n            .get_current_block()\n            .write_opcode(CompilerOpcode::Pop);\n    }\n\n    Ok(())\n}\n\nfn do_struct_compile(sd: &StructDecl, params: &mut CompileParams) -> CompilationResult {\n    let self_name = StringLiteral {\n        loc: sd.loc.clone(),\n        value: sd.name.value.clone(),\n    };\n    self_name.do_compile(params)?;\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::BuildStruct, sd.loc.clone());\n\n    // Inject mixin includes for each item in the inherits list\n    let body = if !sd.inherits.is_empty() {\n        let mut new_body = vec![];\n        for mixin_expr in &sd.inherits {\n            new_body.push(StructEntry::MixinInclude(Box::new(MixinIncludeDecl {\n                loc: sd.loc.clone(),\n                what: mixin_expr.clone(),\n            })));\n        }\n        new_body.extend_from_slice(&sd.body);\n        new_body\n    } else {\n        sd.body.clone()\n    };\n\n    emit_type_members_compile(&body, params, false)\n}\n\nfn do_enum_compile<T>(\n    ed: &EnumDecl,\n    params: &mut CompileParams,\n    name_writer: T,\n) -> CompilationResult\nwhere\n    T: FnOnce(&str, &mut CompileParams) -> CompilationResult,\n{\n    let self_name = StringLiteral {\n        loc: ed.loc.clone(),\n        value: ed.name.value.clone(),\n    };\n    self_name.do_compile(params)?;\n\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::BuildEnum, ed.loc.clone());\n    name_writer(&ed.name.value, params)?;\n\n    let mut cases: Vec<EnumCaseDecl> = vec![];\n    let mut entries: Vec<StructEntry> = vec![];\n\n    for ede in &ed.body {\n        match ede {\n            EnumDeclEntry::EnumCaseDecl(case) => cases.push(case.clone()),\n            EnumDeclEntry::StructEntry(entry) => entries.push(entry.clone()),\n        }\n    }\n\n    let enum_helper_methods = generate_case_helpers_extension_for_enum(&cases);\n    emit_type_members_compile(&enum_helper_methods, params, false)?;\n\n    emit_type_members_compile(&entries, params, false)?;\n\n    emit_enum_cases(&cases, params)?;\n\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::Pop, ed.loc.clone());\n\n    Ok(())\n}\n\nfn generate_is_case_helper_for_enum(case: &EnumCaseDecl) -> MethodDecl {\n    let return_true_stmt = ReturnStatement::from(&Expression::from(&Identifier {\n        loc: case.loc.clone(),\n        value: \"true\".to_owned(),\n    }));\n\n    let return_false_stmt = ReturnStatement::from(&Expression::from(&Identifier {\n        loc: case.loc.clone(),\n        value: \"false\".to_owned(),\n    }));\n\n    let match_case_pattern = MatchPatternEnumCase {\n        loc: case.loc.clone(),\n        case: case.name.clone(),\n        payload: None,\n    };\n\n    let match_rule = MatchRule {\n        loc: case.loc.clone(),\n        patterns: vec![MatchPattern::MatchPatternEnumCase(match_case_pattern)],\n        then: CodeBlock::from(&Statement::ReturnStatement(return_true_stmt)),\n    };\n\n    let match_statement = MatchStatement {\n        loc: case.loc.clone(),\n        expr: Expression::from(&Identifier {\n            loc: case.loc.clone(),\n            value: \"this\".to_owned(),\n        }),\n        rules: vec![match_rule],\n        els: Some(ElsePiece {\n            loc: case.loc.clone(),\n            then: CodeBlock::from(&Statement::ReturnStatement(return_false_stmt)),\n        }),\n    };\n\n    let method_body = FunctionBody {\n        code: CodeBlock::from(&Statement::MatchStatement(match_statement)),\n    };\n    MethodDecl {\n        loc: case.loc.clone(),\n        access: MethodAccess::Instance,\n        name: Identifier {\n            loc: case.loc.clone(),\n            value: format!(\"is_{}\", case.name.value),\n        },\n        args: ArgumentList::empty(case.loc.clone()),\n        body: method_body,\n    }\n}\n\nfn generate_unwap_case_helper_for_enum(case: &EnumCaseDecl) -> MethodDecl {\n    assert!(case.payload.is_some());\n\n    let return_true_stmt = ReturnStatement::from(&Expression::from(&Identifier {\n        loc: case.loc.clone(),\n        value: \"__case_payload\".to_owned(),\n    }));\n\n    let assert_false_stmt = AssertStatement {\n        loc: case.loc.clone(),\n        val: Expression::from(&Identifier {\n            loc: case.loc.clone(),\n            value: \"false\".to_owned(),\n        }),\n    };\n\n    let match_case_pattern = MatchPatternEnumCase {\n        loc: case.loc.clone(),\n        case: case.name.clone(),\n        payload: Some(DeclarationId {\n            loc: case.loc.clone(),\n            name: Identifier {\n                loc: case.loc.clone(),\n                value: \"__case_payload\".to_owned(),\n            },\n            ty: None,\n        }),\n    };\n\n    let match_rule = MatchRule {\n        loc: case.loc.clone(),\n        patterns: vec![MatchPattern::MatchPatternEnumCase(match_case_pattern)],\n        then: CodeBlock::from(&Statement::ReturnStatement(return_true_stmt)),\n    };\n\n    let match_statement = MatchStatement {\n        loc: case.loc.clone(),\n        expr: Expression::from(&Identifier {\n            loc: case.loc.clone(),\n            value: \"this\".to_owned(),\n        }),\n        rules: vec![match_rule],\n        els: Some(ElsePiece {\n            loc: case.loc.clone(),\n            then: CodeBlock::from(&Statement::AssertStatement(assert_false_stmt)),\n        }),\n    };\n\n    let method_body = FunctionBody {\n        code: CodeBlock::from(&Statement::MatchStatement(match_statement)),\n    };\n    MethodDecl {\n        loc: case.loc.clone(),\n        access: MethodAccess::Instance,\n        name: Identifier {\n            loc: case.loc.clone(),\n            value: format!(\"unwrap_{}\", case.name.value),\n        },\n        args: ArgumentList::empty(case.loc.clone()),\n        body: method_body,\n    }\n}\n\nfn generate_case_helpers_extension_for_enum(cases: &[EnumCaseDecl]) -> Vec<StructEntry> {\n    let mut entries: Vec<StructEntry> = vec![];\n\n    for case in cases {\n        entries.push(StructEntry::Method(Box::new(\n            generate_is_case_helper_for_enum(case),\n        )));\n        if case.payload.is_some() {\n            entries.push(StructEntry::Method(Box::new(\n                generate_unwap_case_helper_for_enum(case),\n            )));\n        }\n    }\n\n    entries\n}\n\n// assume your parent enum is on the stack\nfn emit_enum_cases(cases: &[EnumCaseDecl], params: &mut CompileParams) -> CompilationResult {\n    for case in cases {\n        case.do_compile(params)?;\n    }\n\n    Ok(())\n}\n\npub(crate) fn compile_from_ast(\n    ast: &ParsedModule,\n    options: &CompilationOptions,\n) -> CompilationResult<CompiledModule, Vec<CompilationError>> {\n    let mut dest = CompiledModule::default();\n    let scope = CompilationScope::module();\n    let mut mod_init_bytecode = FunctionBuilder::default();\n    let cflow = ControlFlowTargets::default();\n\n    let mut c_params = CompileParams {\n        module: &mut dest,\n        scope: &scope,\n        writer: &mut mod_init_bytecode,\n        cflow: &cflow,\n        options,\n    };\n\n    ast.do_compile(&mut c_params)?;\n\n    Ok(dest)\n}\n\npub(crate) fn compile_from_source(\n    src: &SourceBuffer,\n    options: &CompilationOptions,\n) -> CompilationResult<CompiledModule, Vec<CompilationError>> {\n    let ast = match source_to_ast(src) {\n        Ok(ast) => ast,\n        Err(err) => {\n            return Err(vec![CompilationError {\n                loc: err.loc,\n                reason: CompilationErrorReason::ParserError(err.msg),\n            }]);\n        }\n    };\n\n    compile_from_ast(&ast, options).map(|mut module| {\n        // The source buffer name is the cannonalized path to the source file if it was created from a file.\n        // Once we check it is an existing file, we can use it to find the widget path.\n        let src_path = PathBuf::from(&src.name);\n\n        module.widget_root_path = if src_path.exists() {\n            // Ensure the source buffer name is a file path\n            debug_assert!(src_path.is_file());\n\n            let mut ancestors = src_path.ancestors();\n            loop {\n                if let Some(widget_path) = ancestors.next() {\n                    let widget_json = widget_path.join(\"widget.json\");\n                    if !widget_json.exists() {\n                        continue;\n                    }\n\n                    break Some(widget_path.to_path_buf());\n                }\n\n                break None;\n            }\n        } else {\n            None\n        };\n\n        module\n    })\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/add_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::AddOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n        for right in &self.right {\n            right.1.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    match right.0 {\n                        aria_parser::ast::AddSymbol::Plus => CompilerOpcode::Add,\n                        aria_parser::ast::AddSymbol::Minus => CompilerOpcode::Sub,\n                    },\n                    self.loc.clone(),\n                );\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/assert_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator};\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::AssertStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.val.do_compile(params)?;\n        let poa = PrintoutAccumulator::default();\n        let poa = self.val.prettyprint(poa).value();\n        let msg_idx = self.insert_const_or_fail(params, ConstantValue::String(poa), &self.loc)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Assert(msg_idx), self.loc.clone());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/assign_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_parser::ast::{\n    DeclarationId, Expression, Identifier, IntLiteral, Primary, Statement, ValDeclEntry,\n    ValDeclStatement,\n};\n\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams, postfix::PostfixValue};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::AssignStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        if self.id.len() != self.val.len() {\n            return Err(crate::do_compile::CompilationError {\n                loc: self.loc.clone(),\n                reason: crate::do_compile::CompilationErrorReason::AssignmentArityMismatch(\n                    self.id.len(),\n                    self.val.len(),\n                ),\n            });\n        }\n        if self.id.len() == 1 {\n            let pv = PostfixValue::from(&self.id[0]);\n            pv.emit_write(&self.val[0], params)\n        } else {\n            let temp_buffer_store = Identifier {\n                loc: self.loc.clone(),\n                value: format!(\"__multiwrite_temp_store{:?}\", self.loc.location),\n            };\n            let zero_val = Expression::from(&Primary::IntLiteral(IntLiteral {\n                loc: self.loc.clone(),\n                base: aria_parser::ast::IntLiteralBase::Decimal,\n                val: \"0\".to_string(),\n            }));\n            let temp_buffer_expression = Expression::from(&temp_buffer_store.clone());\n\n            Statement::ValDeclStatement(ValDeclStatement {\n                loc: self.loc.clone(),\n                decls: vec![ValDeclEntry {\n                    loc: self.loc.clone(),\n                    id: DeclarationId::from(&temp_buffer_store),\n                    val: zero_val,\n                }],\n            })\n            .do_compile(params)?;\n\n            for rhs in self.val.iter().rev() {\n                rhs.do_compile(params)?;\n            }\n\n            for lhs in self.id.iter() {\n                params.scope.emit_write(\n                    &temp_buffer_store.value,\n                    &mut params.module.constants,\n                    params.writer.get_current_block(),\n                    lhs.loc.clone(),\n                )?;\n                let pv = PostfixValue::from(lhs);\n                pv.emit_write(&temp_buffer_expression, params)?;\n            }\n\n            Ok(())\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/break_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::BreakStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        if let Some(break_target) = &params.cflow.break_dest {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::Jump(break_target.clone()),\n                    self.loc.clone(),\n                );\n            Ok(())\n        } else {\n            Err(CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::FlowControlNotAllowed,\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/code_block.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::CodeBlock {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let c_scope = params.scope.child();\n        let mut c_params = CompileParams {\n            module: params.module,\n            scope: &c_scope,\n            writer: params.writer,\n            cflow: params.cflow,\n            options: params.options,\n        };\n\n        for entry in &self.entries {\n            entry.do_compile(&mut c_params)?;\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/comp_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::CompOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n        if let Some(right) = &self.right {\n            right.1.do_compile(params)?;\n            match right.0 {\n                aria_parser::ast::CompSymbol::Equal => params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Equal, self.loc.clone()),\n                aria_parser::ast::CompSymbol::NotEqual => params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Equal, self.loc.clone())\n                    .write_opcode_and_source_info(CompilerOpcode::Not, self.loc.clone()),\n                aria_parser::ast::CompSymbol::Isa => params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Isa, self.loc.clone()),\n            };\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/continue_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ContinueStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        if let Some(continue_target) = &params.cflow.continue_dest {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::Jump(continue_target.clone()),\n                    self.loc.clone(),\n                );\n            Ok(())\n        } else {\n            Err(CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::FlowControlNotAllowed,\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/enum_case_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::enum_case_attribs::CASE_HAS_PAYLOAD;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::EnumCaseDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult<()> {\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Dup, self.loc.clone());\n        let attrib_byte = match &self.payload {\n            Some(expr) => {\n                expr.do_compile(params)?;\n                CASE_HAS_PAYLOAD\n            }\n            None => 0,\n        };\n        let name_idx = self.insert_const_or_fail(\n            params,\n            ConstantValue::String(self.name.value.clone()),\n            &self.loc,\n        )?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::BindCase(attrib_byte, name_idx),\n                self.loc.clone(),\n            );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/enum_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams, do_enum_compile},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::EnumDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        do_enum_compile(self, params, |name, params| {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(CompilerOpcode::Dup, self.loc.clone());\n            params\n                .scope\n                .emit_untyped_define(\n                    name,\n                    &mut params.module.constants,\n                    params.writer.get_current_block(),\n                    self.loc.clone(),\n                )\n                .map_err(Into::into)\n        })\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::Expression {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match self {\n            Self::LogOperation(lo) => lo.do_compile(params),\n            Self::LambdaFunction(lf) => lf.do_compile(params),\n            Self::TernaryExpression(te) => te.do_compile(params),\n            Self::TryUnwrapExpression(te) => te.do_compile(params),\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/expression_list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a, usize> for aria_parser::ast::ExpressionList {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult<usize> {\n        for expr in &self.expressions {\n            expr.do_compile(params)?;\n        }\n        Ok(self.expressions.len())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/expression_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ExpressionStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        if let Some(val) = &self.val {\n            val.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    crate::builder::compiler_opcodes::CompilerOpcode::Pop,\n                    self.loc.clone(),\n                );\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/extension_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{\n    CompilationResult, CompileNode, CompileParams, MixinIncludeDecl, StructEntry,\n    emit_type_members_compile,\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ExtensionDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.target.do_compile(params)?;\n\n        // Inject mixin includes for each item in the inherits list\n        if !self.inherits.is_empty() {\n            let mut new_body = vec![];\n            for mixin_expr in &self.inherits {\n                new_body.push(StructEntry::MixinInclude(Box::new(MixinIncludeDecl {\n                    loc: self.loc.clone(),\n                    what: mixin_expr.clone(),\n                })));\n            }\n            new_body.extend_from_slice(&self.body);\n\n            emit_type_members_compile(&new_body, params, true)\n        } else {\n            emit_type_members_compile(&self.body, params, true)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/float_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::FloatLiteral {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let fp_val = self\n            .val\n            .strip_suffix(\"f\")\n            .unwrap_or(&self.val)\n            .parse::<f64>()\n            .map_err(|_| CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::InvalidLiteral(self.val.clone()),\n            })?;\n        let const_idx =\n            self.insert_const_or_fail(params, ConstantValue::Float(fp_val.into()), &self.loc)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Push(const_idx), self.loc.clone());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/for_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::{\n    AssignStatement, BreakStatement, CodeBlock, DeclarationId, ElsePiece, Expression, Identifier,\n    IfCondPiece, IfPiece, IfStatement, MatchRule, MatchStatement, ParenExpression,\n    PostfixExpression, PostfixRvalue, PostfixTerm, PostfixTermEnumCase, Primary, Statement,\n    ThrowStatement, UnaryOperation, ValDeclEntry, ValDeclStatement, WhileStatement,\n};\n\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nmacro_rules! val_decl_statement {\n    ($loc:expr, $id:expr, $val:expr) => {\n        Statement::ValDeclStatement(ValDeclStatement {\n            loc: $loc,\n            decls: vec![ValDeclEntry {\n                loc: $loc,\n                id: DeclarationId::from(&Identifier {\n                    loc: $loc,\n                    value: $id.clone(),\n                }),\n                val: $val,\n            }],\n        })\n    };\n}\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ForStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        // the else block makes the logic here quite tricky and worth commenting\n        // essentially it boils down to the following logic:\n\n        // {\n        //     val iter = <iterator expr>;\n        //     val any_hit = false;\n        //     while true {\n        //         val next = iter.next();\n        //         match next {\n        //             case Some(x) => {\n        //                 any_hit = true;\n        //                 val x = next.value;\n        //                 <body of the loop>\n        //             }\n        //             case None => {\n        //                 if !any_hit {\n        //                     <else clause if any>\n        //                 }\n        //                 break; # out of the while loop\n        //             }\n        //         }\n        //     }\n        // }\n\n        // this is the iterator\n        let iter_name_ident = Identifier {\n            loc: self.loc.clone(),\n            value: format!(\"__for__iter__{}\", self.id.value),\n        };\n\n        // this is the next value from the iterator (the Maybe, not the actual object)\n        let val_next_ident = Identifier {\n            loc: self.loc.clone(),\n            value: format!(\"__for__next__{}\", self.id.value),\n        };\n\n        // this becomes true when the for {} body is executed at least once\n        let any_hit_ident = Identifier {\n            loc: self.loc.clone(),\n            value: format!(\"__for__any_hit__{}\", self.id.value),\n        };\n\n        let fetch_iter_val = val_decl_statement!(\n            self.loc.clone(),\n            iter_name_ident.value,\n            Expression::from(&PostfixExpression::method_call(\n                &Primary::ParenExpression(ParenExpression::from(&self.expr)),\n                \"iterator\",\n                &[]\n            ))\n        );\n\n        let any_hit_val = val_decl_statement!(\n            self.loc.clone(),\n            any_hit_ident.value,\n            Expression::from(&Identifier {\n                loc: self.loc.clone(),\n                value: \"false\".to_owned(),\n            })\n        );\n\n        let true_cond = Expression::from(&Identifier {\n            loc: self.loc.clone(),\n            value: \"true\".to_owned(),\n        });\n\n        // val __for__next__ = __for__iter__.next();\n        let fetch_next_val = val_decl_statement!(\n            self.loc.clone(),\n            val_next_ident.value,\n            Expression::from(&PostfixExpression::method_call(\n                &Primary::Identifier(iter_name_ident.clone()),\n                \"next\",\n                &[]\n            ))\n        );\n\n        // !__for__any_hit\n        let check_any_hit_expr = Expression::from(&UnaryOperation {\n            loc: self.loc.clone(),\n            operand: Some(aria_parser::ast::UnarySymbol::Exclamation),\n            postfix: PostfixRvalue {\n                loc: self.loc.clone(),\n                expr: PostfixExpression::from(&Primary::Identifier(any_hit_ident.clone())),\n            },\n        });\n\n        // if !__for__any_hit { <do the else block if any> }\n        let if_not_any_hit = IfCondPiece {\n            loc: self.loc.clone(),\n            expression: Box::new(check_any_hit_expr),\n            then: CodeBlock {\n                loc: self.loc.clone(),\n                entries: if let Some(els) = &self.els {\n                    els.then.entries.clone()\n                } else {\n                    vec![]\n                },\n            },\n        };\n\n        let if_not_any_hit = Statement::IfStatement(IfStatement {\n            loc: self.loc.clone(),\n            iff: IfPiece {\n                content: if_not_any_hit,\n            },\n            elsif: vec![],\n            els: None,\n        });\n\n        // __for__any_hit = true;\n        let assign_to_any_hit = Statement::AssignStatement(AssignStatement {\n            loc: self.loc.clone(),\n            id: vec![PostfixExpression::from(&Primary::Identifier(\n                any_hit_ident.clone(),\n            ))],\n            val: vec![true_cond.clone()],\n        });\n\n        // case Some(x)\n        let case_some_blk = MatchRule::enum_and_case(\n            self.loc.clone(),\n            \"Maybe\",\n            \"Some\",\n            Some(self.id.clone()),\n            CodeBlock {\n                loc: self.loc.clone(),\n                entries: vec![assign_to_any_hit, Statement::CodeBlock(self.then.clone())],\n            },\n        );\n\n        // case None\n        let case_none_block = MatchRule::enum_and_case(\n            self.loc.clone(),\n            \"Maybe\",\n            \"None\",\n            None,\n            CodeBlock {\n                loc: self.loc.clone(),\n                entries: vec![\n                    if_not_any_hit,\n                    Statement::BreakStatement(BreakStatement {\n                        loc: self.loc.clone(),\n                    }),\n                ],\n            },\n        );\n\n        // RuntimeError::UnexpectedType\n        let unexpected_type = Expression::from(&PostfixExpression {\n            loc: self.loc.clone(),\n            base: Primary::Identifier(Identifier {\n                loc: self.loc.clone(),\n                value: \"RuntimeError\".to_owned(),\n            }),\n            terms: vec![PostfixTerm::PostfixTermEnumCase(PostfixTermEnumCase {\n                loc: self.loc.clone(),\n                id: Identifier {\n                    loc: self.loc.clone(),\n                    value: \"UnexpectedType\".to_owned(),\n                },\n                payload: None,\n            })],\n        });\n\n        // throw UT\n        let throw_ut = Statement::ThrowStatement(ThrowStatement {\n            loc: self.loc.clone(),\n            val: unexpected_type,\n        });\n\n        // read __for__next\n        let read_for_next = Expression::from(&PostfixExpression::from(&Primary::Identifier(\n            val_next_ident.clone(),\n        )));\n\n        // match __for__next { some(x), none, els => throw UT }\n        let match_for_next = Statement::MatchStatement(MatchStatement {\n            loc: self.loc.clone(),\n            expr: read_for_next,\n            rules: vec![case_some_blk, case_none_block],\n            els: Some(ElsePiece {\n                loc: self.loc.clone(),\n                then: CodeBlock {\n                    loc: self.loc.clone(),\n                    entries: vec![throw_ut],\n                },\n            }),\n        });\n\n        // while (true) { fetch_next; match_next; }\n        let while_body = CodeBlock {\n            loc: self.loc.clone(),\n            entries: vec![fetch_next_val, match_for_next],\n        };\n\n        // this is while true { do the body }\n        let w = Statement::WhileStatement(WhileStatement {\n            loc: self.loc.clone(),\n            cond: true_cond,\n            then: while_body,\n            els: None,\n        });\n\n        // create the iterator and the any_hit marker, then loop over the iterator\n        let blk = CodeBlock {\n            loc: self.loc.clone(),\n            entries: vec![fetch_iter_val, any_hit_val, w],\n        };\n        blk.do_compile(params)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/function_body.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::FunctionBody {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.code.do_compile(params)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/function_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::function_attribs::FUNC_ACCEPTS_VARARG;\n\nuse crate::{\n    builder::{compiler_opcodes::CompilerOpcode, func::FunctionBuilder},\n    constant_value::{CompiledCodeObject, ConstantValue},\n    do_compile::{\n        CompilationError, CompilationResult, CompileNode, CompileParams, ControlFlowTargets,\n        emit_args_at_target,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::FunctionDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let cflow = ControlFlowTargets::default();\n        let mut writer = FunctionBuilder::default();\n        let mut c_params = CompileParams {\n            module: params.module,\n            scope: params.scope,\n            writer: &mut writer,\n            cflow: &cflow,\n            options: params.options,\n        };\n\n        let argc = emit_args_at_target(&[], &self.args, &[], &mut c_params)?;\n\n        self.body.do_compile(&mut c_params)?;\n        self.return_unit_value(&mut c_params, &self.loc)?;\n\n        let co = match writer.write(&params.module.constants, params.options) {\n            Ok(c) => c,\n            Err(er) => {\n                return Err(CompilationError {\n                    loc: self.loc.clone(),\n                    reason: er,\n                });\n            }\n        };\n        let frame_size = params.scope.as_function_root().unwrap().num_locals();\n        let line_table = writer.write_line_table().clone();\n        let a = if self.args.vararg {\n            FUNC_ACCEPTS_VARARG\n        } else {\n            0_u8\n        };\n        let cco = CompiledCodeObject {\n            name: self.name.value.clone(),\n            attribute: a,\n            body: co,\n            required_argc: argc.required_args,\n            default_argc: argc.default_args,\n            loc: self.loc.clone(),\n            line_table,\n            frame_size,\n        };\n        let cco_idx =\n            self.insert_const_or_fail(params, ConstantValue::CompiledCodeObject(cco), &self.loc)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Push(cco_idx), self.loc.clone())\n            .write_opcode_and_source_info(CompilerOpcode::BuildFunction, self.loc.clone());\n\n        for uplv in params\n            .scope\n            .as_function_root()\n            .unwrap()\n            .uplevels\n            .borrow()\n            .iter()\n        {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::StoreUplevel(uplv.idx_in_uplevel),\n                    self.loc.clone(),\n                );\n        }\n\n        params\n            .scope\n            .get_module_scope()\n            .unwrap()\n            .emit_untyped_define(\n                &self.name.value,\n                &mut params.module.constants,\n                params.writer.get_current_block(),\n                self.loc.clone(),\n            )?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/identifier.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::Identifier {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        params.scope.emit_read(\n            &self.value,\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/if_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::IfStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let after_all = params\n            .writer\n            .append_block_at_end(&format!(\"after_all_{}\", self.loc));\n\n        // a trivial if is of the form\n        // if foo {\n        //     bar\n        //}\n        // in which case, we can simply emit a jump to \"after all\", i.e. compile as\n        // <foo>\n        // JUMP_FALSE <after_all>\n        // <then>...\n        // JUMP <after_all> since the block needs to be terminated\n        // <after_all>...\n        let is_trivial_if = self.elsif.is_empty() && self.els.is_none();\n\n        // compile the first if\n        {\n            self.iff.content.expression.do_compile(params)?;\n            let if_true = params.writer.insert_block_after(\n                &format!(\"if_true_{}\", self.loc),\n                &params.writer.get_current_block(),\n            );\n            let if_false = params\n                .writer\n                .insert_block_after(&format!(\"if_false_{}\", self.loc), &if_true);\n            if is_trivial_if {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::JumpFalse(after_all.clone()),\n                        self.iff.content.loc.clone(),\n                    );\n            } else {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::JumpConditionally(if_true.clone(), if_false.clone()),\n                        self.iff.content.loc.clone(),\n                    );\n                params.writer.set_current_block(if_true);\n            }\n            self.iff.content.then.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::Jump(after_all.clone()),\n                    self.iff.content.loc.clone(),\n                );\n            params.writer.set_current_block(if_false);\n        }\n\n        // compile every elsif\n        {\n            for elsif in &self.elsif {\n                elsif.content.expression.do_compile(params)?;\n                let if_true = params.writer.insert_block_after(\n                    &format!(\"if_true_{}\", self.loc),\n                    &params.writer.get_current_block(),\n                );\n                let if_false = params\n                    .writer\n                    .insert_block_after(&format!(\"if_false_{}\", self.loc), &if_true);\n\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::JumpConditionally(if_true.clone(), if_false.clone()),\n                        elsif.content.then.loc.clone(),\n                    );\n                params.writer.set_current_block(if_true);\n                elsif.content.then.do_compile(params)?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::Jump(after_all.clone()),\n                        elsif.content.loc.clone(),\n                    );\n                params.writer.set_current_block(if_false);\n            }\n        }\n\n        // compile the else\n        {\n            if let Some(els) = &self.els {\n                els.then.do_compile(params)?;\n            }\n        }\n\n        if !is_trivial_if {\n            // jump to after all\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::Jump(after_all.clone()),\n                    self.loc.clone(),\n                );\n        }\n        params.writer.set_current_block(after_all);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/import_from_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::BuiltinValueId;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ImportFromStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let path_idx = self.insert_const_or_fail(\n            params,\n            ConstantValue::String(self.from.to_dotted_string()),\n            &self.loc,\n        )?;\n\n        match &self.what {\n            aria_parser::ast::ImportTarget::IdentifierList(identifiers) => {\n                for identifier in &identifiers.identifiers {\n                    let ident_idx = self.insert_const_or_fail(\n                        params,\n                        ConstantValue::String(identifier.value.clone()),\n                        &self.loc,\n                    )?;\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::Import(path_idx),\n                            self.loc.clone(),\n                        )\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::ReadAttribute(ident_idx),\n                            self.loc.clone(),\n                        );\n                    params.scope.emit_untyped_define(\n                        &identifier.value,\n                        &mut params.module.constants,\n                        params.writer.get_current_block(),\n                        self.loc.clone(),\n                    )?;\n                }\n            }\n            aria_parser::ast::ImportTarget::All => {\n                let path_idx = self.insert_const_or_fail(\n                    params,\n                    ConstantValue::String(self.from.to_dotted_string()),\n                    &self.loc,\n                )?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::Import(path_idx),\n                        self.loc.clone(),\n                    )\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::PushRuntimeValue(BuiltinValueId::ThisModule),\n                        self.loc.clone(),\n                    )\n                    .write_opcode_and_source_info(CompilerOpcode::LiftModule, self.loc.clone());\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/import_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ImportStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let path_idx = self.insert_const_or_fail(\n            params,\n            ConstantValue::String(self.what.to_dotted_string()),\n            &self.loc,\n        )?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Import(path_idx), self.loc.clone());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/int_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::IntLiteral {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let inp_str = &self.val.replace('_', \"\");\n\n        // I don't particularly like this code, but I don't know an easy way to write\n        // if X { Result<A,E> } else if XX { Result<B,E> } ... . map_err(...)? as B;\n        // basically, some paths want to generate a u64 and some want to generate an i64,\n        // but all need to converge on i64 in the end.\n        let val = if let Some(hex_str) = inp_str.strip_prefix(\"0x\") {\n            u64::from_str_radix(hex_str, 16).map_err(|_| CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::InvalidLiteral(inp_str.to_owned()),\n            })? as i64\n        } else if let Some(bin_str) = inp_str.strip_prefix(\"0b\") {\n            u64::from_str_radix(bin_str, 2).map_err(|_| CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::InvalidLiteral(inp_str.to_owned()),\n            })? as i64\n        } else if let Some(oct_str) = inp_str.strip_prefix(\"0o\") {\n            i64::from_str_radix(oct_str, 8).map_err(|_| CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::InvalidLiteral(inp_str.to_owned()),\n            })?\n        } else {\n            inp_str.parse::<i64>().map_err(|_| CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::InvalidLiteral(inp_str.to_owned()),\n            })?\n        };\n\n        if val == 0 {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(CompilerOpcode::Push0, self.loc.clone());\n        } else if val == 1 {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(CompilerOpcode::Push1, self.loc.clone());\n        } else {\n            let const_idx =\n                self.insert_const_or_fail(params, ConstantValue::Integer(val), &self.loc)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(CompilerOpcode::Push(const_idx), self.loc.clone());\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/lambda.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::{FunctionBody, FunctionDecl, Identifier};\n\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::LambdaFunction {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let body: FunctionBody = From::from(self.body.as_ref());\n        let f_name = format!(\"<anon_f_{}>\", self.loc);\n        let f_obj = FunctionDecl {\n            loc: body.loc().clone(),\n            name: Identifier {\n                loc: self.loc.clone(),\n                value: f_name.clone(),\n            },\n            args: self.args.clone(),\n            body,\n        };\n\n        let f_body_scope = params.scope.closure(params.writer.get_current_block());\n        let mut f_body_params = CompileParams {\n            module: params.module,\n            scope: &f_body_scope,\n            writer: params.writer,\n            cflow: params.cflow,\n            options: params.options,\n        };\n\n        f_obj.do_compile(&mut f_body_params)?;\n\n        params.scope.emit_read(\n            &f_name,\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/list_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ListLiteral {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let count = self\n            .items\n            .expressions\n            .iter()\n            .map(|arg| arg.do_compile(params))\n            .count();\n\n        if count > u32::MAX as usize {\n            Err(CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::ListTooLarge,\n            })\n        } else {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::BuildList(count as u32),\n                    self.loc.clone(),\n                );\n            Ok(())\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/logical_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::LogOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n        for right in &self.right {\n            match right.0 {\n                // xor and bitwise operators do not shortcircut\n                aria_parser::ast::LogSymbol::Ampersand => {\n                    right.1.do_compile(params)?;\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::BitwiseAnd, self.loc.clone());\n                }\n                aria_parser::ast::LogSymbol::Pipe => {\n                    right.1.do_compile(params)?;\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::BitwiseOr, self.loc.clone());\n                }\n                aria_parser::ast::LogSymbol::Caret => {\n                    right.1.do_compile(params)?;\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::Xor, self.loc.clone());\n                }\n                aria_parser::ast::LogSymbol::DoubleAmpersand => {\n                    let bb_and_true = params\n                        .writer\n                        .append_block_at_end(&format!(\"bb_and_true{}\", self.loc));\n                    let bb_and_done = params\n                        .writer\n                        .append_block_at_end(&format!(\"bb_and_done{}\", self.loc));\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::JumpTrue(bb_and_true.clone()),\n                            self.loc.clone(),\n                        );\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::PushFalse, self.loc.clone());\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::Jump(bb_and_done.clone()),\n                            self.loc.clone(),\n                        );\n                    params.writer.set_current_block(bb_and_true);\n                    right.1.do_compile(params)?; // true and X == X\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::Jump(bb_and_done.clone()),\n                            self.loc.clone(),\n                        );\n                    params.writer.set_current_block(bb_and_done);\n                }\n                aria_parser::ast::LogSymbol::DoublePipe => {\n                    let bb_or_true = params\n                        .writer\n                        .append_block_at_end(&format!(\"bb_or_true{}\", self.loc));\n                    let bb_or_done = params\n                        .writer\n                        .append_block_at_end(&format!(\"bb_or_done{}\", self.loc));\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::JumpTrue(bb_or_true.clone()),\n                            self.loc.clone(),\n                        );\n                    right.1.do_compile(params)?; // false or X == X\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::Jump(bb_or_done.clone()),\n                            self.loc.clone(),\n                        );\n                    params.writer.set_current_block(bb_or_true);\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::PushTrue, self.loc.clone());\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(\n                            CompilerOpcode::Jump(bb_or_done.clone()),\n                            self.loc.clone(),\n                        );\n                    params.writer.set_current_block(bb_or_done);\n                }\n            }\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/match_pattern.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MatchPattern {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match self {\n            Self::MatchPatternComp(e) => e.do_compile(params),\n            Self::MatchPatternRel(e) => e.do_compile(params),\n            Self::MatchPatternEnumCase(e) => e.do_compile(params),\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/match_pattern_comp.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MatchPatternComp {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.expr.do_compile(params)?;\n        match self.op {\n            aria_parser::ast::CompSymbol::Equal => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Equal, self.loc.clone());\n            }\n            aria_parser::ast::CompSymbol::NotEqual => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Equal, self.loc.clone())\n                    .write_opcode_and_source_info(CompilerOpcode::Not, self.loc.clone());\n            }\n            aria_parser::ast::CompSymbol::Isa => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Isa, self.loc.clone());\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/match_pattern_enum_case.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_parser::ast::SourcePointer;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nfn emit_case_without_payload(\n    _: &SourcePointer,\n    case: &aria_parser::ast::Identifier,\n    params: &mut CompileParams,\n) -> CompilationResult {\n    let case_name_idx =\n        case.insert_const_or_fail(params, ConstantValue::String(case.value.clone()), &case.loc)?;\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(\n            CompilerOpcode::EnumCheckIsCase(case_name_idx),\n            case.loc.clone(),\n        );\n    Ok(())\n}\n\nfn emit_case_with_payload(\n    loc: &SourcePointer,\n    case: &aria_parser::ast::Identifier,\n    payload: &aria_parser::ast::DeclarationId,\n    params: &mut CompileParams,\n) -> CompilationResult {\n    emit_case_without_payload(loc, case, params)?;\n    // jump here when any intermediate check fails, this will push false on the stack\n    let payload_check_failed = params\n        .writer\n        .append_block_at_end(&format!(\"payload_chck_failed{}\", case.loc));\n    // this is where match expects to continue, with either true or false on the stack\n    // and possibly a local symbol bound on success\n    let payload_check_aftermath = params\n        .writer\n        .append_block_at_end(&format!(\"payload_chck_aftermath{}\", case.loc));\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(\n            CompilerOpcode::JumpFalse(payload_check_failed.clone()),\n            loc.clone(),\n        );\n    // we know we have a case match - now extract the payload\n    params.scope.emit_read(\n        \"__match_control_expr\",\n        &mut params.module.constants,\n        params.writer.get_current_block(),\n        payload.loc.clone(),\n    )?;\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::EnumTryExtractPayload, payload.loc.clone());\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(\n            CompilerOpcode::JumpFalse(payload_check_failed.clone()),\n            loc.clone(),\n        );\n    // if we're here, we know we have a payload - bind it to a local variable now\n    if let Some(ty) = &payload.ty {\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Dup, loc.clone());\n        ty.do_compile(params)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Isa, loc.clone())\n            .write_opcode_and_source_info(\n                CompilerOpcode::JumpFalse(payload_check_failed.clone()),\n                loc.clone(),\n            );\n    }\n    params.scope.emit_untyped_define(\n        &payload.name.value,\n        &mut params.module.constants,\n        params.writer.get_current_block(),\n        loc.clone(),\n    )?;\n    // if we're still here, we passed all checks - push true and jump to aftermath\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::PushTrue, loc.clone())\n        .write_opcode_and_source_info(\n            CompilerOpcode::Jump(payload_check_aftermath.clone()),\n            loc.clone(),\n        );\n    params.writer.set_current_block(payload_check_failed);\n    params\n        .writer\n        .get_current_block()\n        .write_opcode_and_source_info(CompilerOpcode::PushFalse, loc.clone())\n        .write_opcode_and_source_info(\n            CompilerOpcode::Jump(payload_check_aftermath.clone()),\n            loc.clone(),\n        );\n    params.writer.set_current_block(payload_check_aftermath);\n    Ok(())\n}\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MatchPatternEnumCase {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match &self.payload {\n            None => emit_case_without_payload(&self.loc, &self.case, params),\n            Some(decl_id) => emit_case_with_payload(&self.loc, &self.case, decl_id, params),\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/match_pattern_rel.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MatchPatternRel {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.expr.do_compile(params)?;\n        match self.op {\n            aria_parser::ast::RelSymbol::Less => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::LessThan, self.loc.clone());\n            }\n            aria_parser::ast::RelSymbol::LessEqual => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::LessThanEqual, self.loc.clone());\n            }\n            aria_parser::ast::RelSymbol::Greater => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::GreaterThan, self.loc.clone());\n            }\n            aria_parser::ast::RelSymbol::GreaterEqual => {\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::GreaterThanEqual,\n                        self.loc.clone(),\n                    );\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/match_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MatchStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let c_scope = params.scope.child();\n        let mut match_param = CompileParams {\n            module: params.module,\n            scope: &c_scope,\n            writer: params.writer,\n            cflow: params.cflow,\n            options: params.options,\n        };\n\n        self.expr.do_compile(&mut match_param)?;\n\n        // store the control expression here so it can be used\n        match_param.scope.emit_untyped_define(\n            \"__match_control_expr\",\n            &mut match_param.module.constants,\n            match_param.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n\n        let match_after = match_param\n            .writer\n            .append_block_at_end(&format!(\"match_after_{}\", self.loc));\n\n        for rule in &self.rules {\n            let r_scope = match_param.scope.child();\n            let mut rule_param = CompileParams {\n                module: match_param.module,\n                scope: &r_scope,\n                writer: match_param.writer,\n                cflow: match_param.cflow,\n                options: match_param.options,\n            };\n\n            let match_hit = rule_param.writer.insert_block_after(\n                &format!(\"match_hit_{}\", rule.loc),\n                &rule_param.writer.get_current_block(),\n            );\n            let match_miss = rule_param\n                .writer\n                .insert_block_after(&format!(\"match_miss_{}\", rule.loc), &match_hit);\n\n            for pattern in &rule.patterns {\n                rule_param.scope.emit_read(\n                    \"__match_control_expr\",\n                    &mut rule_param.module.constants,\n                    rule_param.writer.get_current_block(),\n                    pattern.loc().clone(),\n                )?;\n                // pattern is going to leave true (hit) or false (miss)\n                // and may add local variables to the scope\n                pattern.do_compile(&mut rule_param)?;\n                rule_param\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::JumpFalse(match_miss.clone()),\n                        pattern.loc().clone(),\n                    );\n            }\n            rule_param\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::Jump(match_hit.clone()),\n                    rule.loc.clone(),\n                );\n            rule_param.writer.set_current_block(match_hit);\n            rule.then.do_compile(&mut rule_param)?;\n            rule_param\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::Jump(match_after.clone()),\n                    rule.loc.clone(),\n                );\n            rule_param.writer.set_current_block(match_miss);\n        }\n\n        if let Some(els) = &self.els {\n            els.then.do_compile(&mut match_param)?;\n        }\n        match_param\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(match_after.clone()),\n                self.loc.clone(),\n            );\n        match_param.writer.set_current_block(match_after);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/method_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_parser::ast::{DeclarationId, Identifier};\nuse haxby_opcodes::function_attribs::{FUNC_ACCEPTS_VARARG, FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\n\nuse crate::{\n    builder::{compiler_opcodes::CompilerOpcode, func::FunctionBuilder},\n    constant_value::{CompiledCodeObject, ConstantValue},\n    do_compile::{\n        CompilationError, CompilationResult, CompileNode, CompileParams, ControlFlowTargets,\n        emit_args_at_target,\n    },\n    scope::CompilationScope,\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MethodDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let attribute = if self.args.vararg {\n            FUNC_ACCEPTS_VARARG\n        } else {\n            0\n        } | FUNC_IS_METHOD\n            | if self.access == aria_parser::ast::MethodAccess::Type {\n                METHOD_ATTRIBUTE_TYPE\n            } else {\n                0\n            };\n\n        let f_scope = CompilationScope::function(params.scope);\n        let cflow = ControlFlowTargets::default();\n        let mut writer = FunctionBuilder::default();\n        let mut c_params = CompileParams {\n            module: params.module,\n            scope: &f_scope,\n            writer: &mut writer,\n            cflow: &cflow,\n            options: params.options,\n        };\n\n        let this_arg = From::from(&DeclarationId {\n            loc: self.loc.clone(),\n            name: Identifier {\n                loc: self.loc.clone(),\n                value: match self.access {\n                    aria_parser::ast::MethodAccess::Instance => \"this\",\n                    aria_parser::ast::MethodAccess::Type => \"This\",\n                }\n                .to_owned(),\n            },\n            ty: None,\n        });\n        let argc = emit_args_at_target(&[this_arg], &self.args, &[], &mut c_params)?;\n\n        self.body.do_compile(&mut c_params)?;\n        self.return_unit_value(&mut c_params, &self.loc)?;\n\n        let frame_size = c_params.scope.as_function_root().unwrap().num_locals();\n\n        let co = match writer.write(&params.module.constants, params.options) {\n            Ok(c) => c,\n            Err(er) => {\n                return Err(CompilationError {\n                    loc: self.loc.clone(),\n                    reason: er,\n                });\n            }\n        };\n        let line_table = writer.write_line_table().clone();\n        let cco = CompiledCodeObject {\n            name: self.name.value.clone(),\n            attribute,\n            body: co,\n            required_argc: argc.required_args,\n            default_argc: argc.default_args,\n            loc: self.loc.clone(),\n            line_table,\n            frame_size,\n        };\n        let cco_idx =\n            self.insert_const_or_fail(params, ConstantValue::CompiledCodeObject(cco), &self.loc)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Push(cco_idx), self.loc.clone());\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/mixin_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_parser::ast::StringLiteral;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams, emit_type_members_compile},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MixinDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let self_name = StringLiteral {\n            loc: self.loc.clone(),\n            value: self.name.value.clone(),\n        };\n        self_name.do_compile(params)?;\n\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::BuildMixin, self.loc.clone())\n            .write_opcode_and_source_info(CompilerOpcode::Dup, self.loc.clone());\n        params.scope.emit_untyped_define(\n            &self.name.value,\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n\n        emit_type_members_compile(&self.body, params, true)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nmod add_operation;\nmod assert_statement;\nmod assign_statement;\nmod break_statement;\nmod code_block;\nmod comp_operation;\nmod continue_statement;\nmod enum_case_decl;\nmod enum_decl;\nmod expression;\nmod expression_list;\nmod expression_statement;\nmod extension_decl;\nmod float_literal;\nmod for_statement;\nmod function_body;\nmod function_decl;\nmod identifier;\nmod if_statement;\nmod import_from_statement;\nmod import_statement;\nmod int_literal;\nmod lambda;\nmod list_literal;\nmod logical_operation;\nmod match_pattern;\nmod match_pattern_comp;\nmod match_pattern_enum_case;\nmod match_pattern_rel;\nmod match_statement;\nmod method_decl;\nmod mixin_decl;\nmod mul_operation;\nmod paren_expression;\nmod parsed_module;\nmod postfix_rvalue;\nmod primary;\nmod rel_operation;\nmod return_statement;\nmod shift_operation;\nmod statement;\nmod string_literal;\nmod struct_decl;\nmod ternary_expression;\nmod throw_statement;\nmod try_block;\nmod try_unwrap_expression;\nmod unary_operation;\nmod val_decl_entry;\nmod val_decl_statement;\nmod while_statement;\nmod write_opeq_statement;\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/mul_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::MulOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n        for right in &self.right {\n            right.1.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    match right.0 {\n                        aria_parser::ast::MulSymbol::Star => CompilerOpcode::Mul,\n                        aria_parser::ast::MulSymbol::Slash => CompilerOpcode::Div,\n                        aria_parser::ast::MulSymbol::Percent => CompilerOpcode::Rem,\n                    },\n                    self.loc.clone(),\n                );\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/paren_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ParenExpression {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.value.do_compile(params)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/parsed_module.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::{ImportFromStatement, ImportPath, ParsedModule};\nuse haxby_opcodes::BuiltinValueId;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::{CompiledCodeObject, ConstantValue},\n    do_compile::{CompilationError, CompilationResult, CompileNode, CompileParams},\n};\n\nmacro_rules! collate_error_if_any {\n    {$expression: expr, $errors: expr} => {\n        if let Err(e) = $expression {\n            $errors.push(e);\n        }\n    }\n}\n\nimpl<'a> CompileNode<'a, (), Vec<CompilationError>> for ParsedModule {\n    fn do_compile(\n        &self,\n        params: &'a mut CompileParams,\n    ) -> CompilationResult<(), Vec<CompilationError>> {\n        let mut errors = vec![];\n\n        if !self\n            .flags\n            .flags\n            .contains(&aria_parser::ast::ModuleFlag::NoStandardLibrary)\n        {\n            let import_core_statement = ImportFromStatement {\n                loc: self.loc.clone(),\n                what: aria_parser::ast::ImportTarget::All,\n                from: ImportPath::from_dotted_string(self.loc.clone(), \"aria.core.builtin\"),\n            };\n            collate_error_if_any!(import_core_statement.do_compile(params), errors);\n        }\n\n        for pf in &self.entries {\n            match pf {\n                aria_parser::ast::TopLevelEntry::ValDeclStatement(v) => {\n                    collate_error_if_any!(v.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::WriteOpEqStatement(w) => {\n                    collate_error_if_any!(w.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::AssignStatement(a) => {\n                    collate_error_if_any!(a.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::FunctionDecl(f) => {\n                    let f_scope = params.scope.function();\n                    let mut f_params = CompileParams {\n                        module: params.module,\n                        scope: &f_scope,\n                        writer: params.writer,\n                        cflow: params.cflow,\n                        options: params.options,\n                    };\n                    collate_error_if_any!(f.do_compile(&mut f_params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::StructDecl(s) => {\n                    collate_error_if_any!(s.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::MixinDecl(m) => {\n                    collate_error_if_any!(m.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::ExtensionDecl(e) => {\n                    collate_error_if_any!(e.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::ExpressionStatement(e) => {\n                    collate_error_if_any!(e.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::AssertStatement(a) => {\n                    collate_error_if_any!(a.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::EnumDecl(e) => {\n                    collate_error_if_any!(e.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::ImportStatement(i) => {\n                    collate_error_if_any!(i.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::ImportFromStatement(i) => {\n                    collate_error_if_any!(i.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::IfStatement(i) => {\n                    collate_error_if_any!(i.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::MatchStatement(m) => {\n                    collate_error_if_any!(m.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::WhileStatement(w) => {\n                    collate_error_if_any!(w.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::ForStatement(f) => {\n                    collate_error_if_any!(f.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::CodeBlock(c) => {\n                    collate_error_if_any!(c.do_compile(params), errors)\n                }\n                aria_parser::ast::TopLevelEntry::TryBlock(t) => {\n                    collate_error_if_any!(t.do_compile(params), errors)\n                }\n            }\n        }\n\n        for flag in &self.flags.flags {\n            if let aria_parser::ast::ModuleFlag::UsesDylib(lib) = flag {\n                let cidx = match self.insert_const_or_fail(\n                    params,\n                    ConstantValue::String(lib.clone()),\n                    &self.loc,\n                ) {\n                    Ok(i) => i,\n                    Err(e) => {\n                        errors.push(e);\n                        return Err(errors);\n                    }\n                };\n                #[allow(deprecated)] // flags have no location info\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode(CompilerOpcode::PushRuntimeValue(BuiltinValueId::ThisModule))\n                    .write_opcode(CompilerOpcode::LoadDylib(cidx));\n            }\n        }\n\n        #[allow(deprecated)] // no entry to ascribe this write to\n        params\n            .writer\n            .get_current_block()\n            .write_opcode(CompilerOpcode::ReturnUnit);\n\n        let co = match params\n            .writer\n            .write(&params.module.constants, params.options)\n        {\n            Ok(c) => c,\n            Err(e) => {\n                errors.push(CompilationError {\n                    loc: self.loc.clone(),\n                    reason: e,\n                });\n                return Err(errors);\n            }\n        };\n\n        let frame_size = 0;\n        let line_table = params.writer.write_line_table().clone();\n        let __entry_cco = CompiledCodeObject {\n            name: \"__entry\".to_owned(),\n            attribute: 0,\n            body: co,\n            required_argc: 0,\n            default_argc: 0,\n            loc: self.loc.clone(),\n            line_table,\n            frame_size,\n        };\n\n        if let Err(e) = self.insert_const_or_fail(\n            params,\n            ConstantValue::CompiledCodeObject(__entry_cco),\n            &self.loc,\n        ) {\n            errors.push(e);\n        }\n\n        if errors.is_empty() {\n            Ok(())\n        } else {\n            Err(errors)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/postfix_rvalue.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams, postfix::PostfixValue};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::PostfixRvalue {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let pv = PostfixValue::from(&self.expr);\n        pv.emit_read(params)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/primary.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::Primary {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match self {\n            Self::IntLiteral(il) => il.do_compile(params),\n            Self::FloatLiteral(fp) => fp.do_compile(params),\n            Self::Identifier(id) => id.do_compile(params),\n            Self::ListLiteral(ll) => ll.do_compile(params),\n            Self::StringLiteral(sl) => sl.do_compile(params),\n            Self::ParenExpression(pe) => pe.do_compile(params),\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/rel_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::RelOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n        if let Some(rhs) = &self.right {\n            rhs.1.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    match rhs.0 {\n                        aria_parser::ast::RelSymbol::Greater => CompilerOpcode::GreaterThan,\n                        aria_parser::ast::RelSymbol::Less => CompilerOpcode::LessThan,\n                        aria_parser::ast::RelSymbol::GreaterEqual => {\n                            CompilerOpcode::GreaterThanEqual\n                        }\n                        aria_parser::ast::RelSymbol::LessEqual => CompilerOpcode::LessThanEqual,\n                    },\n                    self.loc.clone(),\n                );\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/return_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ReturnStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        if let Some(val) = &self.val {\n            val.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(CompilerOpcode::Return, self.loc.clone());\n        } else {\n            self.return_unit_value(params, &self.loc)?;\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/shift_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ShiftOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n        if let Some(rhs) = &self.right {\n            rhs.1.do_compile(params)?;\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    match rhs.0 {\n                        aria_parser::ast::ShiftSymbol::Leftward => CompilerOpcode::ShiftLeft,\n                        aria_parser::ast::ShiftSymbol::Rightward => CompilerOpcode::ShiftRight,\n                    },\n                    self.loc.clone(),\n                );\n        };\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::Statement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match self {\n            Self::ValDeclStatement(l) => l.do_compile(params),\n            Self::AssignStatement(a) => a.do_compile(params),\n            Self::WriteOpEqStatement(w) => w.do_compile(params),\n            Self::IfStatement(i) => i.do_compile(params),\n            Self::MatchStatement(m) => m.do_compile(params),\n            Self::WhileStatement(w) => w.do_compile(params),\n            Self::ForStatement(f) => f.do_compile(params),\n            Self::ReturnStatement(r) => r.do_compile(params),\n            Self::ThrowStatement(t) => t.do_compile(params),\n            Self::TryBlock(t) => t.do_compile(params),\n            Self::AssertStatement(a) => a.do_compile(params),\n            Self::CodeBlock(c) => c.do_compile(params),\n            Self::ExpressionStatement(e) => e.do_compile(params),\n            Self::BreakStatement(b) => b.do_compile(params),\n            Self::ContinueStatement(c) => c.do_compile(params),\n            Self::StructDecl(s) => s.do_compile(params),\n            Self::EnumDecl(e) => e.do_compile(params),\n            Self::FunctionDecl(f) => {\n                let f_scope = params.scope.closure(params.writer.get_current_block());\n                let mut f_params = CompileParams {\n                    module: params.module,\n                    scope: &f_scope,\n                    writer: params.writer,\n                    cflow: params.cflow,\n                    options: params.options,\n                };\n                f.do_compile(&mut f_params)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/string_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::StringLiteral {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let const_idx = self.insert_const_or_fail(\n            params,\n            ConstantValue::String(self.value.clone()),\n            &self.loc,\n        )?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Push(const_idx), self.loc.clone());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/struct_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams, do_struct_compile};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::StructDecl {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        do_struct_compile(self, params)?;\n\n        params.scope.emit_untyped_define(\n            &self.name.value,\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/ternary_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\nuse aria_parser::ast::TernaryExpression;\n\nimpl<'a> CompileNode<'a> for TernaryExpression {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.condition.do_compile(params)?;\n\n        let false_branch = params\n            .writer\n            .append_block_at_end(&format!(\"ternary_false_{}\", self.loc));\n        let end_branch = params\n            .writer\n            .append_block_at_end(&format!(\"ternary_end_{}\", self.loc));\n\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::JumpFalse(false_branch.clone()),\n                self.loc.clone(),\n            );\n\n        self.true_expression.do_compile(params)?;\n\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(end_branch.clone()),\n                self.loc.clone(),\n            );\n\n        params.writer.set_current_block(false_branch);\n\n        self.false_expression.do_compile(params)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(end_branch.clone()),\n                self.loc.clone(),\n            );\n\n        params.writer.set_current_block(end_branch);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/throw_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ThrowStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.val.do_compile(params)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Throw, self.loc.clone());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/try_block.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::TryBlock {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let try_block = params.writer.insert_block_after(\n            &format!(\"try_{}\", &self.body.loc),\n            &params.writer.get_current_block(),\n        );\n        let catch_block = params\n            .writer\n            .insert_block_after(&format!(\"catch_{}\", &self.catch.loc), &try_block);\n        let after_block = params\n            .writer\n            .insert_block_after(&format!(\"try_after_catch_{}\", &self.body.loc), &catch_block);\n\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(try_block.clone()),\n                self.loc.clone(),\n            );\n        params.writer.set_current_block(try_block);\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::TryEnter(catch_block.clone()),\n                self.loc.clone(),\n            );\n        self.body.do_compile(params)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::TryExit, self.loc.clone());\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(after_block.clone()),\n                self.loc.clone(),\n            );\n        params.writer.set_current_block(catch_block);\n\n        let catch_scope = params.scope.child();\n        let mut catch_params = CompileParams {\n            module: params.module,\n            scope: &catch_scope,\n            writer: params.writer,\n            cflow: params.cflow,\n            options: params.options,\n        };\n        catch_params.scope.emit_untyped_define(\n            &self.id.value,\n            &mut catch_params.module.constants,\n            catch_params.writer.get_current_block(),\n            self.id.loc.clone(),\n        )?;\n\n        self.catch.do_compile(&mut catch_params)?;\n        catch_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(after_block.clone()),\n                self.loc.clone(),\n            );\n        catch_params.writer.set_current_block(after_block);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/try_unwrap_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::TryUnwrapExpression;\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    constant_value::ConstantValue,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for TryUnwrapExpression {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.left.do_compile(params)?;\n\n        let try_unwrap_protocol_idx = params\n            .module\n            .constants\n            .insert(ConstantValue::String(\"try_unwrap_protocol\".to_string()))\n            .map_err(|_| CompilationError {\n                loc: self.loc.clone(),\n                reason: CompilationErrorReason::TooManyConstants,\n            })?;\n\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::PushBuiltinTy(BuiltinTypeId::Result),\n                self.loc.clone(),\n            )\n            .write_opcode_and_source_info(\n                CompilerOpcode::ReadAttribute(try_unwrap_protocol_idx),\n                self.loc.clone(),\n            )\n            .write_opcode_and_source_info(CompilerOpcode::Call(1), self.loc.clone())\n            .write_opcode_and_source_info(\n                CompilerOpcode::TryUnwrapProtocol(\n                    haxby_opcodes::try_unwrap_protocol_mode::FLAG_TO_CALLER,\n                ),\n                self.loc.clone(),\n            );\n\n        let fallback_block = params\n            .writer\n            .append_block_at_end(&format!(\"try_unwrap_fallback_{}\", self.loc));\n        let end_block = params\n            .writer\n            .append_block_at_end(&format!(\"try_unwrap_end_{}\", self.loc));\n\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::JumpConditionally(end_block.clone(), fallback_block.clone()),\n                self.loc.clone(),\n            );\n\n        params.writer.set_current_block(fallback_block);\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Pop, self.loc.clone());\n        self.right.do_compile(params)?;\n        params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(end_block.clone()),\n                self.loc.clone(),\n            );\n\n        params.writer.set_current_block(end_block);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/unary_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::UnaryOperation {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        self.postfix.do_compile(params)?;\n        if let Some(op) = self.operand {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    match op {\n                        aria_parser::ast::UnarySymbol::Exclamation => CompilerOpcode::Not,\n                        aria_parser::ast::UnarySymbol::Minus => CompilerOpcode::Neg,\n                    },\n                    self.loc.clone(),\n                );\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/val_decl_entry.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{\n        CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n    },\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ValDeclEntry {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match self.id.name.value.as_str() {\n            \"true\" | \"false\" => {\n                return Err(CompilationError {\n                    loc: self.loc.clone(),\n                    reason: CompilationErrorReason::ReservedIdentifier(self.id.name.value.clone()),\n                });\n            }\n            _ => {}\n        };\n\n        self.val.do_compile(params)?;\n        if let Some(ty) = &self.id.ty {\n            ty.do_compile(params)?;\n        } else {\n            params\n                .writer\n                .get_current_block()\n                .write_opcode_and_source_info(\n                    CompilerOpcode::PushBuiltinTy(BuiltinTypeId::Any),\n                    self.loc.clone(),\n                );\n        }\n        params.scope.emit_typed_define(\n            &self.id.name.value,\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n        params.scope.emit_write(\n            &self.id.name.value,\n            &mut params.module.constants,\n            params.writer.get_current_block(),\n            self.loc.clone(),\n        )?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/val_decl_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::ValDeclStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        for decl in &self.decls {\n            decl.do_compile(params)?;\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/while_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builder::compiler_opcodes::CompilerOpcode,\n    do_compile::{CompilationResult, CompileNode, CompileParams, ControlFlowTargets},\n};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::WhileStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let first_check = params\n            .writer\n            .append_block_at_end(&format!(\"first_check_{}\", self.loc));\n        let check = params\n            .writer\n            .append_block_at_end(&format!(\"check_{}\", self.loc));\n        let then = params\n            .writer\n            .append_block_at_end(&format!(\"then_{}\", self.loc));\n        let els = params\n            .writer\n            .append_block_at_end(&format!(\"else_{}\", self.loc));\n        let after = params\n            .writer\n            .append_block_at_end(&format!(\"after_{}\", self.loc));\n\n        let w_cflow = ControlFlowTargets {\n            break_dest: Some(after.clone()),\n            continue_dest: Some(check.clone()),\n        };\n\n        let mut c_params = CompileParams {\n            module: params.module,\n            scope: params.scope,\n            writer: params.writer,\n            cflow: &w_cflow,\n            options: params.options,\n        };\n\n        // the logic here is a bit tricky because of the else:\n        // jump to first_check, which will check the condition\n        // if true, jump to then, which will execute the body\n        // if false, jump to else, which will then jump to after\n        // then will jump back to check, which will check the condition again\n        // if the condition is still true, it will jump to then again\n        // if the condition is false, it will jump to after (not to else)\n\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::Jump(first_check.clone()),\n                self.loc.clone(),\n            );\n        c_params.writer.set_current_block(first_check.clone());\n        self.cond.do_compile(&mut c_params)?;\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::JumpTrue(then.clone()),\n                self.then.loc.clone(),\n            );\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Jump(els.clone()), self.loc.clone());\n\n        c_params.writer.set_current_block(check.clone());\n        self.cond.do_compile(&mut c_params)?;\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(\n                CompilerOpcode::JumpTrue(then.clone()),\n                self.then.loc.clone(),\n            );\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Jump(after.clone()), self.loc.clone());\n        c_params.writer.set_current_block(then);\n        self.then.do_compile(&mut c_params)?;\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Jump(check.clone()), self.loc.clone());\n\n        c_params.writer.set_current_block(els);\n        if let Some(els) = &self.els {\n            els.then.do_compile(&mut c_params)?;\n        }\n        c_params\n            .writer\n            .get_current_block()\n            .write_opcode_and_source_info(CompilerOpcode::Jump(after.clone()), self.loc.clone());\n        c_params.writer.set_current_block(after);\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/nodes/write_opeq_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::{\n    AddOperation, AddSymbol, AssignStatement, CompOperation, Expression, LogOperation,\n    MulOperation, MulSymbol, ParenExpression, PostfixExpression, PostfixRvalue, Primary,\n    RelOperation, ShiftOperation, ShiftSymbol, UnaryOperation,\n};\n\nuse crate::do_compile::{CompilationResult, CompileNode, CompileParams};\n\nimpl<'a> CompileNode<'a> for aria_parser::ast::WriteOpEqStatement {\n    fn do_compile(&self, params: &'a mut CompileParams) -> CompilationResult {\n        let rhs_as_unary = UnaryOperation::from(&PostfixRvalue::from(&PostfixExpression::from(\n            &Primary::ParenExpression(ParenExpression {\n                loc: self.val.loc().clone(),\n                value: Box::new(self.val.clone()),\n            }),\n        )));\n\n        let rhs_as_mul = MulOperation::from(&rhs_as_unary);\n\n        let final_expr = match self.op {\n            aria_parser::ast::AddEqSymbol::PlusEq => {\n                let add_op = AddOperation {\n                    loc: self.loc.clone(),\n                    left: MulOperation::from(&UnaryOperation::from(&PostfixRvalue::from(&self.id))),\n                    right: vec![(AddSymbol::Plus, rhs_as_mul)],\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&ShiftOperation::from(&add_op)),\n                )))\n            }\n            aria_parser::ast::AddEqSymbol::MinusEq => {\n                let add_op = AddOperation {\n                    loc: self.loc.clone(),\n                    left: MulOperation::from(&UnaryOperation::from(&PostfixRvalue::from(&self.id))),\n                    right: vec![(AddSymbol::Minus, rhs_as_mul)],\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&ShiftOperation::from(&add_op)),\n                )))\n            }\n\n            aria_parser::ast::AddEqSymbol::StarEq => {\n                let mo = MulOperation {\n                    loc: self.loc.clone(),\n                    left: UnaryOperation::from(&PostfixRvalue::from(&self.id)),\n                    right: vec![(MulSymbol::Star, rhs_as_unary)],\n                };\n                let add_op = AddOperation {\n                    loc: self.loc.clone(),\n                    left: mo,\n                    right: vec![],\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&ShiftOperation::from(&add_op)),\n                )))\n            }\n            aria_parser::ast::AddEqSymbol::SlashEq => {\n                let mo = MulOperation {\n                    loc: self.loc.clone(),\n                    left: UnaryOperation::from(&PostfixRvalue::from(&self.id)),\n                    right: vec![(MulSymbol::Slash, rhs_as_unary)],\n                };\n                let add_op = AddOperation {\n                    loc: self.loc.clone(),\n                    left: mo,\n                    right: vec![],\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&ShiftOperation::from(&add_op)),\n                )))\n            }\n            aria_parser::ast::AddEqSymbol::PercentEq => {\n                let mo = MulOperation {\n                    loc: self.loc.clone(),\n                    left: UnaryOperation::from(&PostfixRvalue::from(&self.id)),\n                    right: vec![(MulSymbol::Percent, rhs_as_unary)],\n                };\n                let add_op = AddOperation {\n                    loc: self.loc.clone(),\n                    left: mo,\n                    right: vec![],\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&ShiftOperation::from(&add_op)),\n                )))\n            }\n\n            aria_parser::ast::AddEqSymbol::ShiftLeftEq => {\n                let shift_op = ShiftOperation {\n                    loc: self.loc.clone(),\n                    left: AddOperation::from(&MulOperation::from(&UnaryOperation::from(\n                        &PostfixRvalue::from(&self.id),\n                    ))),\n                    right: Some((\n                        ShiftSymbol::Leftward,\n                        AddOperation::from(&MulOperation::from(&rhs_as_unary)),\n                    )),\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&shift_op),\n                )))\n            }\n            aria_parser::ast::AddEqSymbol::ShiftRightEq => {\n                let shift_op = ShiftOperation {\n                    loc: self.loc.clone(),\n                    left: AddOperation::from(&MulOperation::from(&UnaryOperation::from(\n                        &PostfixRvalue::from(&self.id),\n                    ))),\n                    right: Some((\n                        ShiftSymbol::Rightward,\n                        AddOperation::from(&MulOperation::from(&rhs_as_unary)),\n                    )),\n                };\n                Expression::from(&LogOperation::from(&CompOperation::from(\n                    &RelOperation::from(&shift_op),\n                )))\n            }\n        };\n\n        let assign_stmt = AssignStatement {\n            loc: self.loc.clone(),\n            id: vec![self.id.clone()],\n            val: vec![final_expr],\n        };\n\n        assign_stmt.do_compile(params)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/do_compile/postfix.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::{Expression, ExpressionList, Identifier, SourcePointer};\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{builder::compiler_opcodes::CompilerOpcode, constant_value::ConstantValue};\n\nuse super::{\n    CompilationError, CompilationErrorReason, CompilationResult, CompileNode, CompileParams,\n};\n\n#[derive(Debug)]\npub(super) struct FieldWrite {\n    pub(super) field: Identifier,\n    pub(super) value: Expression,\n}\n\n#[derive(Debug)]\npub(super) struct IndexWrite {\n    pub(super) index: ExpressionList,\n    pub(super) value: Expression,\n}\n\n#[allow(clippy::large_enum_variant)]\n#[derive(Debug)]\npub(super) enum ObjWrite {\n    Field(FieldWrite),\n    Index(IndexWrite),\n}\n\nimpl ObjWrite {\n    fn loc(&self) -> &SourcePointer {\n        match self {\n            ObjWrite::Field(f) => &f.field.loc,\n            ObjWrite::Index(i) => &i.index.loc,\n        }\n    }\n}\n\n#[allow(clippy::large_enum_variant)]\npub(super) enum PostfixValue {\n    Primary(Box<aria_parser::ast::Primary>),\n    Attribute(Box<PostfixValue>, Box<Identifier>),\n    Call(Box<PostfixValue>, Box<ExpressionList>, SourcePointer),\n    Case(Box<PostfixValue>, Box<Identifier>, Option<Expression>),\n    Index(Box<PostfixValue>, Box<aria_parser::ast::ExpressionList>),\n    ObjWrite(Box<PostfixValue>, Vec<ObjWrite>),\n    TryProtocol(\n        Box<PostfixValue>,\n        Box<aria_parser::ast::PostfixTermTryProtocol>,\n    ),\n}\n\nimpl<'a> PostfixValue {\n    pub(super) fn emit_read(&self, params: &'a mut CompileParams) -> CompilationResult {\n        match self {\n            PostfixValue::Primary(primary) => primary.do_compile(params),\n            PostfixValue::Call(base, args, loc) => {\n                for expr in args.expressions.iter().rev() {\n                    expr.do_compile(params)?;\n                }\n                let argc = args.expressions.len();\n                base.emit_read(params)?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(CompilerOpcode::Call(argc as u8), loc.clone());\n                Ok(())\n            }\n            PostfixValue::Case(base, case, payload) => {\n                if let Some(p) = payload {\n                    p.do_compile(params)?;\n                }\n                base.emit_read(params)?;\n                let identifier_idx = match params\n                    .module\n                    .constants\n                    .insert(ConstantValue::String(case.value.clone()))\n                {\n                    Ok(c) => c,\n                    Err(_) => {\n                        return Err(CompilationError {\n                            loc: case.loc.clone(),\n                            reason: CompilationErrorReason::TooManyConstants,\n                        });\n                    }\n                };\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::NewEnumVal(payload.is_some(), identifier_idx),\n                        case.loc.clone(),\n                    );\n                Ok(())\n            }\n            PostfixValue::Index(base, index) => {\n                base.emit_read(params)?;\n                index.do_compile(params)?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::ReadIndex(index.expressions.len() as u8),\n                        index.loc.clone(),\n                    );\n                Ok(())\n            }\n            PostfixValue::Attribute(base, identifier) => {\n                let identifier_idx = match params\n                    .module\n                    .constants\n                    .insert(ConstantValue::String(identifier.value.clone()))\n                {\n                    Ok(c) => c,\n                    Err(_) => {\n                        return Err(CompilationError {\n                            loc: identifier.loc.clone(),\n                            reason: CompilationErrorReason::TooManyConstants,\n                        });\n                    }\n                };\n                base.emit_read(params)?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::ReadAttribute(identifier_idx),\n                        identifier.loc.clone(),\n                    );\n                Ok(())\n            }\n            PostfixValue::ObjWrite(base, terms) => {\n                base.emit_read(params)?;\n                for term in terms {\n                    params\n                        .writer\n                        .get_current_block()\n                        .write_opcode_and_source_info(CompilerOpcode::Dup, term.loc().clone());\n                    match term {\n                        ObjWrite::Field(field_write) => {\n                            let identifier_idx = params\n                                .module\n                                .constants\n                                .insert(ConstantValue::String(field_write.field.value.clone()))\n                                .map_err(|_| CompilationError {\n                                    loc: field_write.field.loc.clone(),\n                                    reason: CompilationErrorReason::TooManyConstants,\n                                })?;\n\n                            field_write.value.do_compile(params)?;\n                            params\n                                .writer\n                                .get_current_block()\n                                .write_opcode_and_source_info(\n                                    CompilerOpcode::WriteAttribute(identifier_idx),\n                                    term.loc().clone(),\n                                );\n                        }\n                        ObjWrite::Index(index_write) => {\n                            index_write.index.do_compile(params)?;\n                            index_write.value.do_compile(params)?;\n                            params\n                                .writer\n                                .get_current_block()\n                                .write_opcode_and_source_info(\n                                    CompilerOpcode::WriteIndex(1_u8),\n                                    term.loc().clone(),\n                                );\n                        }\n                    }\n                }\n                Ok(())\n            }\n            PostfixValue::TryProtocol(base, tp) => {\n                let mode = match tp.mode {\n                    aria_parser::ast::TryProtocolMode::Return => {\n                        haxby_opcodes::try_unwrap_protocol_mode::PROPAGATE_ERROR\n                    }\n                    aria_parser::ast::TryProtocolMode::Assert => {\n                        haxby_opcodes::try_unwrap_protocol_mode::ASSERT_ERROR\n                    }\n                };\n\n                base.emit_read(params)?;\n\n                let try_unwrap_protocol_idx = params\n                    .module\n                    .constants\n                    .insert(ConstantValue::String(\"try_unwrap_protocol\".to_string()))\n                    .map_err(|_| CompilationError {\n                        loc: tp.loc.clone(),\n                        reason: CompilationErrorReason::TooManyConstants,\n                    })?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::PushBuiltinTy(BuiltinTypeId::Result),\n                        tp.loc.clone(),\n                    )\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::ReadAttribute(try_unwrap_protocol_idx),\n                        tp.loc.clone(),\n                    )\n                    .write_opcode_and_source_info(CompilerOpcode::Call(1), tp.loc.clone())\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::TryUnwrapProtocol(mode),\n                        tp.loc.clone(),\n                    );\n                Ok(())\n            }\n        }\n    }\n\n    pub(super) fn emit_write(\n        &self,\n        val: &aria_parser::ast::Expression,\n        params: &'a mut CompileParams,\n    ) -> CompilationResult {\n        match self {\n            PostfixValue::Primary(primary) => match primary.as_ref() {\n                aria_parser::ast::Primary::Identifier(id) => {\n                    val.do_compile(params)?;\n                    params.scope.emit_write(\n                        &id.value,\n                        &mut params.module.constants,\n                        params.writer.get_current_block(),\n                        primary.loc().clone(),\n                    )?;\n                    Ok(())\n                }\n                _ => Err(CompilationError {\n                    loc: primary.loc().clone(),\n                    reason: CompilationErrorReason::ReadOnlyValue,\n                }),\n            },\n            PostfixValue::Call(.., loc) => Err(CompilationError {\n                loc: loc.clone(),\n                reason: CompilationErrorReason::ReadOnlyValue,\n            }),\n            PostfixValue::Case(_, case, _) => Err(CompilationError {\n                loc: case.loc.clone(),\n                reason: CompilationErrorReason::ReadOnlyValue,\n            }),\n            PostfixValue::Index(base, index) => {\n                base.emit_read(params)?;\n                index.do_compile(params)?;\n                val.do_compile(params)?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::WriteIndex(index.expressions.len() as u8),\n                        index.loc.clone(),\n                    );\n                Ok(())\n            }\n            PostfixValue::Attribute(base, identifier) => {\n                let identifier_idx = match params\n                    .module\n                    .constants\n                    .insert(ConstantValue::String(identifier.value.clone()))\n                {\n                    Ok(c) => c,\n                    Err(_) => {\n                        return Err(CompilationError {\n                            loc: identifier.loc.clone(),\n                            reason: CompilationErrorReason::TooManyConstants,\n                        });\n                    }\n                };\n                base.emit_read(params)?;\n                val.do_compile(params)?;\n                params\n                    .writer\n                    .get_current_block()\n                    .write_opcode_and_source_info(\n                        CompilerOpcode::WriteAttribute(identifier_idx),\n                        identifier.loc.clone(),\n                    );\n                Ok(())\n            }\n            PostfixValue::ObjWrite(_, terms) => {\n                let loc = terms.first().map(|x| x.loc()).unwrap_or(val.loc()).clone();\n                Err(CompilationError {\n                    loc,\n                    reason: CompilationErrorReason::WriteOnlyValue,\n                })\n            }\n            PostfixValue::TryProtocol(_, tp) => Err(CompilationError {\n                loc: tp.loc.clone(),\n                reason: CompilationErrorReason::ReadOnlyValue,\n            }),\n        }\n    }\n}\n\nimpl From<&aria_parser::ast::PostfixExpression> for PostfixValue {\n    fn from(value: &aria_parser::ast::PostfixExpression) -> Self {\n        let mut current = PostfixValue::Primary(Box::new(value.base.clone()));\n        for term in &value.terms {\n            match term {\n                aria_parser::ast::PostfixTerm::PostfixTermAttribute(attr) => {\n                    current = PostfixValue::Attribute(Box::new(current), Box::new(attr.id.clone()))\n                }\n                aria_parser::ast::PostfixTerm::PostfixTermIndex(index) => {\n                    current = PostfixValue::Index(Box::new(current), Box::new(index.index.clone()))\n                }\n                aria_parser::ast::PostfixTerm::PostfixTermCall(call) => {\n                    current = PostfixValue::Call(\n                        Box::new(current),\n                        Box::new(call.args.clone()),\n                        call.loc.clone(),\n                    )\n                }\n                aria_parser::ast::PostfixTerm::PostfixTermEnumCase(case) => {\n                    current = PostfixValue::Case(\n                        Box::new(current),\n                        Box::new(case.id.clone()),\n                        case.payload.clone(),\n                    )\n                }\n                aria_parser::ast::PostfixTerm::PostfixTermObjectWrite(wrt) => {\n                    use aria_parser::ast::PostfixTermWrite::{\n                        PostfixTermFieldWrite, PostfixTermIndexWrite,\n                    };\n\n                    let mut terms = vec![];\n                    for term in &wrt.terms.terms {\n                        match term {\n                            PostfixTermFieldWrite(term) => {\n                                let expr = if let Some(expr) = &term.val {\n                                    expr.clone()\n                                } else {\n                                    Expression::from(&term.id)\n                                };\n                                terms.push(ObjWrite::Field(FieldWrite {\n                                    field: term.id.clone(),\n                                    value: expr,\n                                }));\n                            }\n                            PostfixTermIndexWrite(term) => {\n                                terms.push(ObjWrite::Index(IndexWrite {\n                                    index: term.idx.clone(),\n                                    value: term.val.clone(),\n                                }));\n                            }\n                        }\n                    }\n                    current = PostfixValue::ObjWrite(Box::new(current), terms)\n                }\n                aria_parser::ast::PostfixTerm::PostfixTermTryProtocol(tp) => {\n                    current = PostfixValue::TryProtocol(Box::new(current), Box::new(tp.clone()))\n                }\n            }\n        }\n\n        current\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/dump/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator};\nuse opcodes::opcode_prettyprint;\n\nuse crate::{\n    bc_reader::BytecodeReader,\n    constant_value::{CompiledCodeObject, ConstantValue, ConstantValues},\n    module::CompiledModule,\n};\n\npub mod opcodes;\n\npub trait StringResolver {\n    fn resolve_compile_time_constant(&self, _: u16) -> Option<String> {\n        None\n    }\n\n    fn resolve_run_time_symbol(&self, _: u32) -> Option<String> {\n        None\n    }\n}\n\nimpl StringResolver for CompiledModule {\n    fn resolve_compile_time_constant(&self, idx: u16) -> Option<String> {\n        match self.constants.values.get(idx as usize) {\n            Some(cv) => {\n                let poa = PrintoutAccumulator::default();\n                let poa = cv.dump(self, poa);\n                Some(poa.value())\n            }\n            _ => None,\n        }\n    }\n}\n\ntrait ModuleDump {\n    fn dump(\n        &self,\n        resolver: &dyn StringResolver,\n        buffer: PrintoutAccumulator,\n    ) -> PrintoutAccumulator;\n}\n\nimpl ModuleDump for ConstantValue {\n    fn dump(\n        &self,\n        resolver: &dyn StringResolver,\n        buffer: PrintoutAccumulator,\n    ) -> PrintoutAccumulator {\n        match self {\n            ConstantValue::Integer(n) => buffer << \"int(\" << n << \")\",\n            ConstantValue::String(s) => buffer << \"str(\\\"\" << s.as_str() << \"\\\")\",\n            ConstantValue::Float(f) => buffer << \"fp(\" << f.raw_value() << \")\",\n            ConstantValue::CompiledCodeObject(cco) => cco.dump(resolver, buffer),\n        }\n    }\n}\n\nimpl ModuleDump for ConstantValues {\n    fn dump(\n        &self,\n        resolver: &dyn StringResolver,\n        buffer: PrintoutAccumulator,\n    ) -> PrintoutAccumulator {\n        let mut dest = buffer;\n        for cv in self.values.iter().enumerate() {\n            dest = dest << \"cv @\" << cv.0 << \" -> \";\n            dest = cv.1.dump(resolver, dest) << \"\\n\"\n        }\n\n        dest\n    }\n}\n\nimpl ModuleDump for CompiledCodeObject {\n    fn dump(\n        &self,\n        resolver: &dyn StringResolver,\n        buffer: PrintoutAccumulator,\n    ) -> PrintoutAccumulator {\n        let mut dest = buffer\n            << \"cco(name:\\\"\"\n            << self.name.as_str()\n            << \" required arguments:\"\n            << self.required_argc\n            << \" default arguments:\"\n            << self.default_argc\n            << \" frame size:\"\n            << self.frame_size\n            << \") bc=\\n\";\n\n        let mut bcr = match BytecodeReader::try_from(self.body.as_slice()) {\n            Ok(bcr) => bcr,\n            Err(e) => {\n                return dest << \"    <invalid bytecode: \" << e.to_string() << \">\\n\";\n            }\n        };\n        let mut op_idx = 0;\n        loop {\n            let idx_str = format!(\"    {op_idx:05}: \");\n            match bcr.read_opcode() {\n                Ok(op) => {\n                    dest = opcode_prettyprint(op, resolver, dest << idx_str);\n                    if let Some(lte) = self.line_table.get(op_idx as u16) {\n                        dest = dest << format!(\" --> {lte}\") << \"\\n\";\n                    } else {\n                        dest = dest << \"\\n\";\n                    }\n                    op_idx += 1;\n                }\n                Err(_) => {\n                    break;\n                }\n            }\n        }\n\n        dest\n    }\n}\n\nimpl PrettyPrintable for CompiledModule {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        self.constants.dump(self, buffer)\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/dump/opcodes.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator;\nuse haxby_opcodes::Opcode;\n\nfn const_best_repr(resolver: &dyn super::StringResolver, idx: u16) -> String {\n    match resolver.resolve_compile_time_constant(idx) {\n        Some(s) => s.to_string(),\n        None => format!(\"invalid const @{idx}\"),\n    }\n}\n\nfn symbol_best_repr(resolver: &dyn super::StringResolver, idx: u32) -> String {\n    match resolver.resolve_run_time_symbol(idx) {\n        Some(s) => s.to_string(),\n        None => format!(\"invalid const @{idx}\"),\n    }\n}\n\nfn try_protocol_mode_to_str(id: u8) -> &'static str {\n    match id {\n        haxby_opcodes::try_unwrap_protocol_mode::PROPAGATE_ERROR => \"RETURN\",\n        haxby_opcodes::try_unwrap_protocol_mode::ASSERT_ERROR => \"ASSERT\",\n        _ => \"Unknown\",\n    }\n}\n\npub fn opcode_prettyprint(\n    opcode: Opcode,\n    resolver: &dyn super::StringResolver,\n    buffer: PrintoutAccumulator,\n) -> PrintoutAccumulator {\n    match opcode {\n        Opcode::Push(idx) => {\n            buffer << \"PUSH(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::PushBuiltinTy(n) => {\n            buffer << \"PUSH_BUILTIN_TY(\" << n.to_u8() << \") [\" << n.name() << \"]\"\n        }\n        Opcode::PushRuntimeValue(n) => {\n            buffer << \"PUSH_RUNTIME_VAL(\" << n.to_u8() << \") [\" << n.name() << \"]\"\n        }\n        Opcode::ReadNamed(idx) => {\n            buffer << \"READ_NAMED(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::WriteNamed(idx) => {\n            buffer << \"WRITE_NAMED(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::TypedefNamed(idx) => {\n            buffer << \"TYPEDEF_NAMED(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::ReadAttribute(idx) => {\n            buffer << \"READ_ATTRIB(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::WriteAttribute(idx) => {\n            buffer << \"WRITE_ATTRIB(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::ReadAttributeSymbol(idx) => {\n            buffer\n                << \"READ_ATTRIB_SYMBOL(#\"\n                << idx\n                << \") [\"\n                << symbol_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::WriteAttributeSymbol(idx) => {\n            buffer\n                << \"WRITE_ATTRIB_SYMBOL(#\"\n                << idx\n                << \") [\"\n                << symbol_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::BindCase(arg, idx) => {\n            buffer\n                << \"BIND_CASE(\"\n                << arg\n                << \",@\"\n                << idx\n                << \") [\"\n                << const_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::BindCaseSymbol(arg, idx) => {\n            buffer\n                << \"BIND_CASE_SYMBOL(\"\n                << arg\n                << \",#\"\n                << idx\n                << \") [\"\n                << symbol_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::NewEnumVal(flag, idx) => {\n            buffer\n                << \"NEW_ENUM_VAL(\"\n                << flag\n                << \",@\"\n                << idx\n                << \") [\"\n                << const_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::NewEnumValSymbol(flag, idx) => {\n            buffer\n                << \"NEW_ENUM_VAL_SYMBOL(\"\n                << flag\n                << \",#\"\n                << idx\n                << \") [\"\n                << symbol_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::EnumCheckIsCase(idx) => {\n            buffer\n                << \"ENUM_CHECK_IS_CASE(@\"\n                << idx\n                << \") [\"\n                << const_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::EnumCheckIsCaseSymbol(idx) => {\n            buffer\n                << \"ENUM_CHECK_IS_CASE_SYMBOL(#\"\n                << idx\n                << \") [\"\n                << symbol_best_repr(resolver, idx)\n                << \"]\"\n        }\n        Opcode::Import(idx) => {\n            buffer << \"IMPORT(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::LoadDylib(idx) => {\n            buffer << \"LOAD_DYLIB(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::Assert(idx) => {\n            buffer << \"ASSERT(@\" << idx << \") [\" << const_best_repr(resolver, idx) << \"]\"\n        }\n        Opcode::TryUnwrapProtocol(mode) => {\n            buffer << \"TRY_UNWRAP_PROTOCOL \" << try_protocol_mode_to_str(mode)\n        }\n        Opcode::Nop\n        | Opcode::Push0\n        | Opcode::Push1\n        | Opcode::PushTrue\n        | Opcode::PushFalse\n        | Opcode::Pop\n        | Opcode::Dup\n        | Opcode::Swap\n        | Opcode::Copy(_)\n        | Opcode::Add\n        | Opcode::Sub\n        | Opcode::Mul\n        | Opcode::Div\n        | Opcode::Rem\n        | Opcode::Neg\n        | Opcode::ShiftLeft\n        | Opcode::ShiftRight\n        | Opcode::Not\n        | Opcode::Equal\n        | Opcode::ReadLocal(_)\n        | Opcode::WriteLocal(_)\n        | Opcode::TypedefLocal(_)\n        | Opcode::ReadIndex(_)\n        | Opcode::WriteIndex(_)\n        | Opcode::ReadUplevel(_)\n        | Opcode::LogicalAnd\n        | Opcode::LogicalOr\n        | Opcode::Xor\n        | Opcode::BitwiseAnd\n        | Opcode::BitwiseOr\n        | Opcode::GreaterThan\n        | Opcode::LessThan\n        | Opcode::GreaterThanEqual\n        | Opcode::LessThanEqual\n        | Opcode::JumpTrue(_)\n        | Opcode::JumpFalse(_)\n        | Opcode::Jump(_)\n        | Opcode::JumpConditionally(..)\n        | Opcode::JumpIfArgSupplied(..)\n        | Opcode::Call(_)\n        | Opcode::Return\n        | Opcode::ReturnUnit\n        | Opcode::TryEnter(_)\n        | Opcode::TryExit\n        | Opcode::Throw\n        | Opcode::BuildList(_)\n        | Opcode::BuildFunction\n        | Opcode::StoreUplevel(_)\n        | Opcode::BuildStruct\n        | Opcode::BuildEnum\n        | Opcode::BuildMixin\n        | Opcode::IncludeMixin\n        | Opcode::EnumTryExtractPayload\n        | Opcode::Isa\n        | Opcode::LiftModule\n        | Opcode::Halt => buffer << opcode.to_string(),\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_parser::ast::{ParsedModule, SourceBuffer};\nuse do_compile::{CompilationError, CompilationResult};\nuse module::CompiledModule;\n\npub mod bc_reader;\npub mod bc_writer;\npub mod builder;\npub mod constant_value;\npub mod do_compile;\npub mod dump;\npub mod line_table;\npub mod module;\npub mod scope;\n\npub struct CompilationOptions {\n    pub optimize: bool,\n    pub dump_builder: bool,\n}\n\nimpl Default for CompilationOptions {\n    fn default() -> Self {\n        Self {\n            optimize: true,\n            dump_builder: false,\n        }\n    }\n}\n\npub fn compile_from_source(\n    src: &SourceBuffer,\n    options: &CompilationOptions,\n) -> CompilationResult<CompiledModule, Vec<CompilationError>> {\n    do_compile::compile_from_source(src, options)\n}\n\npub fn compile_from_ast(\n    ast: &ParsedModule,\n    options: &CompilationOptions,\n) -> CompilationResult<CompiledModule, Vec<CompilationError>> {\n    do_compile::compile_from_ast(ast, options)\n}\n"
  },
  {
    "path": "compiler-lib/src/line_table.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::RefCell, collections::HashMap, rc::Rc};\n\nuse aria_parser::ast::SourcePointer;\n\n#[derive(Default)]\nstruct LineTableImpl {\n    map: RefCell<HashMap<u16, SourcePointer>>,\n}\n\n#[derive(Clone, Default)]\npub struct LineTable {\n    imp: Rc<LineTableImpl>,\n}\n\nimpl LineTable {\n    pub fn insert(&self, idx: u16, ptr: SourcePointer) {\n        self.imp.map.borrow_mut().insert(idx, ptr);\n    }\n\n    pub fn get(&self, idx: u16) -> Option<SourcePointer> {\n        self.imp.map.borrow().get(&idx).cloned()\n    }\n}\n\nimpl PartialEq for LineTable {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for LineTable {}\n"
  },
  {
    "path": "compiler-lib/src/module.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::path::PathBuf;\n\nuse crate::constant_value::{CompiledCodeObject, ConstantValue, ConstantValues};\n\n#[derive(Default)]\npub struct CompiledModule {\n    pub constants: ConstantValues,\n    pub widget_root_path: Option<PathBuf>,\n}\n\nimpl CompiledModule {\n    pub fn load_indexed_const(&self, idx: u16) -> Option<ConstantValue> {\n        self.constants.get(idx as usize)\n    }\n\n    // relies on __entry being the last code object stored in the module\n    // after everything else is compiled\n    pub fn load_entry_code_object(&self) -> CompiledCodeObject {\n        let cco = self\n            .constants\n            .get(self.constants.len() - 1)\n            .expect(\"missing __entry constant\");\n\n        cco.as_compiled_code_object()\n            .expect(\"__entry constant is not a code object\")\n            .clone()\n    }\n}\n"
  },
  {
    "path": "compiler-lib/src/scope.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::RefCell, collections::HashMap, rc::Rc};\n\nuse aria_parser::ast::SourcePointer;\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{\n    builder::{block::BasicBlock, compiler_opcodes::CompilerOpcode},\n    constant_value::ConstantValues,\n};\n\ntrait Numeric<Output = Self> {\n    fn zero() -> Output;\n\n    fn one() -> Output;\n}\n\nimpl Numeric for u8 {\n    fn zero() -> u8 {\n        0_u8\n    }\n\n    fn one() -> u8 {\n        1_u8\n    }\n}\n\nimpl Numeric for u16 {\n    fn zero() -> u16 {\n        0_u16\n    }\n\n    fn one() -> u16 {\n        1_u16\n    }\n}\n\nstruct IndexProviderImpl<T>\nwhere\n    T: std::ops::AddAssign<T> + Numeric + Copy,\n{\n    next_idx: T,\n}\n\nimpl<T> Default for IndexProviderImpl<T>\nwhere\n    T: std::ops::AddAssign<T> + Numeric + Copy,\n{\n    fn default() -> Self {\n        Self {\n            next_idx: T::zero(),\n        }\n    }\n}\n\nimpl<T> IndexProviderImpl<T>\nwhere\n    T: std::ops::AddAssign<T> + Numeric + Copy,\n{\n    fn next(&mut self) -> T {\n        let current = self.next_idx;\n        self.next_idx += T::one();\n        current\n    }\n\n    fn get_max_index(&self) -> T {\n        self.next_idx\n    }\n}\n\npub enum ScopeErrorReason {\n    TooManyConstants,\n    OverlyDeepClosure,\n    NoSuchIdentifier(String),\n}\n\npub struct ScopeError {\n    pub loc: SourcePointer,\n    pub reason: ScopeErrorReason,\n}\n\npub type ScopeResult<T = ()> = Result<T, ScopeError>;\n\n#[derive(Default)]\npub struct ModuleRootScope {\n    symbols: RefCell<HashMap<String, u16>>,\n}\n\nimpl ModuleRootScope {\n    pub fn emit_typed_define(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        let symbol_idx = match consts.insert(crate::constant_value::ConstantValue::String(\n            name.to_owned(),\n        )) {\n            Ok(c) => c,\n            Err(_) => {\n                return Err(ScopeError {\n                    loc,\n                    reason: ScopeErrorReason::TooManyConstants,\n                });\n            }\n        };\n        self.symbols\n            .borrow_mut()\n            .insert(name.to_owned(), symbol_idx);\n        dest.write_opcode_and_source_info(CompilerOpcode::TypedefNamed(symbol_idx), loc);\n        Ok(())\n    }\n\n    pub fn emit_write(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::WriteNamed(*existing_idx), loc);\n            Ok(())\n        } else {\n            let symbol_idx = match consts.insert(crate::constant_value::ConstantValue::String(\n                name.to_owned(),\n            )) {\n                Ok(c) => c,\n                Err(_) => {\n                    return Err(ScopeError {\n                        loc,\n                        reason: ScopeErrorReason::TooManyConstants,\n                    });\n                }\n            };\n            dest.write_opcode_and_source_info(CompilerOpcode::WriteNamed(symbol_idx), loc);\n            Ok(())\n        }\n    }\n\n    pub fn emit_read(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::ReadNamed(*existing_idx), loc);\n        } else {\n            let symbol_idx = match consts.insert(crate::constant_value::ConstantValue::String(\n                name.to_owned(),\n            )) {\n                Ok(c) => c,\n                Err(_) => {\n                    return Err(ScopeError {\n                        loc,\n                        reason: ScopeErrorReason::TooManyConstants,\n                    });\n                }\n            };\n            dest.write_opcode_and_source_info(CompilerOpcode::ReadNamed(symbol_idx), loc);\n        }\n        Ok(())\n    }\n\n    fn resolve_uplevel_symbol(\n        &self,\n        _: &str,\n        _: BasicBlock,\n        _: SourcePointer,\n        _: bool,\n    ) -> ScopeResult<Option<UplevelSymbolResolution>> {\n        Ok(None)\n    }\n}\n\npub struct ModuleChildScope {\n    symbols: RefCell<HashMap<String, u16>>,\n    parent: CompilationScope,\n}\n\nimpl ModuleChildScope {\n    fn new(parent: CompilationScope) -> Self {\n        Self {\n            symbols: Default::default(),\n            parent,\n        }\n    }\n\n    pub fn emit_typed_define(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        let symbol_idx = match consts.insert(crate::constant_value::ConstantValue::String(\n            name.to_owned(),\n        )) {\n            Ok(c) => c,\n            Err(_) => {\n                return Err(ScopeError {\n                    loc,\n                    reason: ScopeErrorReason::TooManyConstants,\n                });\n            }\n        };\n        self.symbols\n            .borrow_mut()\n            .insert(name.to_owned(), symbol_idx);\n        dest.write_opcode_and_source_info(CompilerOpcode::TypedefNamed(symbol_idx), loc);\n        Ok(())\n    }\n\n    pub fn emit_write(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::WriteNamed(*existing_idx), loc);\n            Ok(())\n        } else {\n            self.parent.emit_write(name, consts, dest, loc)\n        }\n    }\n\n    pub fn emit_read(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::ReadNamed(*existing_idx), loc);\n            Ok(())\n        } else {\n            self.parent.emit_read(name, consts, dest, loc)\n        }\n    }\n\n    fn resolve_uplevel_symbol(\n        &self,\n        _: &str,\n        _: BasicBlock,\n        _: SourcePointer,\n        _: bool,\n    ) -> ScopeResult<Option<UplevelSymbolResolution>> {\n        Ok(None)\n    }\n}\n\n#[derive(Copy, Clone)]\npub(crate) struct UplevelInfo {\n    pub idx_in_uplevel: u8,\n}\n\n#[derive(Copy, Clone)]\nstruct UplevelSymbolResolution {\n    depth: u8,\n    index_at_depth: u8,\n}\n\npub struct FunctionRootScope {\n    symbols: RefCell<HashMap<String, u8>>,\n    index_provider: RefCell<IndexProviderImpl<u8>>,\n    parent: CompilationScope,\n    lexical_parent: Option<(CompilationScope, BasicBlock)>,\n    pub(crate) uplevels: RefCell<Vec<UplevelInfo>>,\n}\n\nimpl FunctionRootScope {\n    fn root_function(parent: CompilationScope) -> Self {\n        Self {\n            symbols: Default::default(),\n            index_provider: Default::default(),\n            parent: parent.get_module_scope().unwrap(),\n            lexical_parent: None,\n            uplevels: Default::default(),\n        }\n    }\n\n    fn closure(lexical_parent: (CompilationScope, BasicBlock)) -> Self {\n        Self {\n            symbols: Default::default(),\n            index_provider: Default::default(),\n            parent: lexical_parent.0.get_module_scope().unwrap(),\n            lexical_parent: Some(lexical_parent),\n            uplevels: Default::default(),\n        }\n    }\n\n    pub fn num_locals(&self) -> u8 {\n        self.index_provider.borrow().get_max_index()\n    }\n\n    pub fn emit_typed_define(\n        &self,\n        name: &str,\n        _: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        let next_idx = self.index_provider.borrow_mut().next();\n        self.symbols.borrow_mut().insert(name.to_owned(), next_idx);\n        dest.write_opcode_and_source_info(CompilerOpcode::TypedefLocal(next_idx), loc);\n        Ok(())\n    }\n\n    pub fn emit_write(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::WriteLocal(*existing_idx), loc);\n            Ok(())\n        } else if let Some(uplevel_info) =\n            self.resolve_uplevel_symbol(name, dest.clone(), loc.clone(), false)?\n        {\n            dest.write_opcode_and_source_info(\n                CompilerOpcode::WriteLocal(uplevel_info.index_at_depth),\n                loc.clone(),\n            );\n            Ok(())\n        } else {\n            self.parent.emit_write(name, consts, dest, loc)\n        }\n    }\n\n    fn store_uplevel_as_local(\n        &self,\n        name: &str,\n        dest: BasicBlock,\n        loc: SourcePointer,\n        uplevel: UplevelSymbolResolution,\n        want_dup_on_stack: bool,\n    ) -> ScopeResult<UplevelSymbolResolution> {\n        if uplevel.depth > 1 {\n            return Err(ScopeError {\n                loc,\n                reason: ScopeErrorReason::OverlyDeepClosure,\n            });\n        }\n        let index_in_local = self.index_provider.borrow_mut().next();\n        self.symbols\n            .borrow_mut()\n            .insert(name.to_owned(), index_in_local);\n        self.uplevels.borrow_mut().push(UplevelInfo {\n            idx_in_uplevel: uplevel.index_at_depth,\n        });\n        dest.write_opcode_and_source_info(\n            CompilerOpcode::ReadUplevel(uplevel.index_at_depth),\n            loc.clone(),\n        );\n        if want_dup_on_stack {\n            dest.write_opcode_and_source_info(CompilerOpcode::Dup, loc.clone());\n        }\n        dest.write_opcode_and_source_info(CompilerOpcode::WriteLocal(index_in_local), loc);\n        Ok(UplevelSymbolResolution {\n            depth: 0,\n            index_at_depth: index_in_local,\n        })\n    }\n\n    pub fn emit_read(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        let maybe_idx = self.symbols.borrow().get(name).cloned();\n        if let Some(existing_idx) = maybe_idx {\n            dest.write_opcode_and_source_info(CompilerOpcode::ReadLocal(existing_idx), loc);\n            return Ok(());\n        }\n\n        if self\n            .resolve_uplevel_symbol(name, dest.clone(), loc.clone(), true)?\n            .is_some()\n        {\n            return Ok(());\n        }\n\n        self.parent.emit_read(name, consts, dest, loc)\n    }\n\n    fn resolve_uplevel_symbol(\n        &self,\n        name: &str,\n        dest: BasicBlock,\n        loc: SourcePointer,\n        want_dup_on_stack: bool,\n    ) -> ScopeResult<Option<UplevelSymbolResolution>> {\n        let maybe_idx = self.symbols.borrow().get(name).cloned();\n        if let Some(existing_idx) = maybe_idx {\n            Ok(Some(UplevelSymbolResolution {\n                depth: 0,\n                index_at_depth: existing_idx,\n            }))\n        } else if let Some(cp) = &self.lexical_parent {\n            let sr =\n                cp.0.resolve_uplevel_symbol(name, cp.1.clone(), loc.clone(), want_dup_on_stack)?;\n            if let Some(sr) = sr {\n                let sr = self.store_uplevel_as_local(name, dest, loc, sr, want_dup_on_stack)?;\n                Ok(Some(sr))\n            } else {\n                Ok(None)\n            }\n        } else {\n            Ok(None)\n        }\n    }\n}\n\npub struct FunctionChildScope {\n    symbols: RefCell<HashMap<String, u8>>,\n    parent: CompilationScope,\n}\n\nimpl FunctionChildScope {\n    fn new(parent: CompilationScope) -> Self {\n        Self {\n            symbols: Default::default(),\n            parent,\n        }\n    }\n\n    fn get_function_root(&self) -> Rc<FunctionRootScope> {\n        match &self.parent {\n            CompilationScope::FunctionRoot(r) => r.clone(),\n            CompilationScope::FunctionChild(c) => c.get_function_root(),\n            _ => panic!(\"function scope should end in a function, not a module\"),\n        }\n    }\n\n    pub fn emit_typed_define(\n        &self,\n        name: &str,\n        _: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        let next_idx = self.get_function_root().index_provider.borrow_mut().next();\n        self.symbols.borrow_mut().insert(name.to_owned(), next_idx);\n        dest.write_opcode_and_source_info(CompilerOpcode::TypedefLocal(next_idx), loc);\n        Ok(())\n    }\n\n    pub fn emit_write(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::WriteLocal(*existing_idx), loc);\n            Ok(())\n        } else {\n            self.parent.emit_write(name, consts, dest, loc)\n        }\n    }\n\n    pub fn emit_read(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            dest.write_opcode_and_source_info(CompilerOpcode::ReadLocal(*existing_idx), loc);\n            Ok(())\n        } else {\n            self.parent.emit_read(name, consts, dest, loc)\n        }\n    }\n\n    fn resolve_uplevel_symbol(\n        &self,\n        name: &str,\n        dest: BasicBlock,\n        loc: SourcePointer,\n        want_dup_on_stack: bool,\n    ) -> ScopeResult<Option<UplevelSymbolResolution>> {\n        if let Some(existing_idx) = self.symbols.borrow().get(name) {\n            Ok(Some(UplevelSymbolResolution {\n                depth: 0,\n                index_at_depth: *existing_idx,\n            }))\n        } else {\n            self.parent\n                .resolve_uplevel_symbol(name, dest, loc, want_dup_on_stack)\n        }\n    }\n}\n\n#[derive(enum_as_inner::EnumAsInner, Clone)]\npub enum CompilationScope {\n    ModuleRoot(Rc<ModuleRootScope>),\n    ModuleChild(Rc<ModuleChildScope>),\n    FunctionRoot(Rc<FunctionRootScope>),\n    FunctionChild(Rc<FunctionChildScope>),\n}\n\nimpl CompilationScope {\n    pub fn module() -> Self {\n        Self::ModuleRoot(Rc::new(ModuleRootScope::default()))\n    }\n\n    pub fn function(&self) -> Self {\n        Self::FunctionRoot(Rc::new(FunctionRootScope::root_function(self.clone())))\n    }\n\n    pub fn closure(&self, dest: BasicBlock) -> Self {\n        Self::FunctionRoot(Rc::new(FunctionRootScope::closure((self.clone(), dest))))\n    }\n\n    pub(crate) fn get_module_scope(&self) -> Option<CompilationScope> {\n        match self {\n            Self::ModuleRoot(_) => Some(self.clone()),\n            Self::ModuleChild(_) => Some(self.clone()),\n            Self::FunctionRoot(fr) => fr.parent.get_module_scope(),\n            Self::FunctionChild(fc) => fc.parent.get_module_scope(),\n        }\n    }\n\n    pub fn child(&self) -> Self {\n        match self {\n            CompilationScope::ModuleRoot(_) | CompilationScope::ModuleChild(_) => {\n                Self::ModuleChild(Rc::new(ModuleChildScope::new(self.clone())))\n            }\n            CompilationScope::FunctionRoot(_) | CompilationScope::FunctionChild(_) => {\n                Self::FunctionChild(Rc::new(FunctionChildScope::new(self.clone())))\n            }\n        }\n    }\n\n    pub fn emit_typed_define(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        match self {\n            Self::ModuleRoot(r) => r.emit_typed_define(name, consts, dest, loc),\n            Self::FunctionRoot(r) => r.emit_typed_define(name, consts, dest, loc),\n            Self::ModuleChild(c) => c.emit_typed_define(name, consts, dest, loc),\n            Self::FunctionChild(c) => c.emit_typed_define(name, consts, dest, loc),\n        }\n    }\n\n    pub fn emit_untyped_define(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        dest.write_opcode_and_source_info(\n            CompilerOpcode::PushBuiltinTy(BuiltinTypeId::Any),\n            loc.clone(),\n        );\n        self.emit_typed_define(name, consts, dest.clone(), loc.clone())?;\n        self.emit_write(name, consts, dest, loc)\n    }\n\n    pub fn emit_write(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        match self {\n            Self::ModuleRoot(r) => r.emit_write(name, consts, dest, loc),\n            Self::FunctionRoot(r) => r.emit_write(name, consts, dest, loc),\n            Self::ModuleChild(c) => c.emit_write(name, consts, dest, loc),\n            Self::FunctionChild(c) => c.emit_write(name, consts, dest, loc),\n        }\n    }\n\n    pub fn emit_read(\n        &self,\n        name: &str,\n        consts: &mut ConstantValues,\n        dest: BasicBlock,\n        loc: SourcePointer,\n    ) -> ScopeResult {\n        match self {\n            Self::ModuleRoot(r) => r.emit_read(name, consts, dest, loc),\n            Self::FunctionRoot(r) => r.emit_read(name, consts, dest, loc),\n            Self::ModuleChild(c) => c.emit_read(name, consts, dest, loc),\n            Self::FunctionChild(c) => c.emit_read(name, consts, dest, loc),\n        }\n    }\n\n    fn resolve_uplevel_symbol(\n        &self,\n        name: &str,\n        dest: BasicBlock,\n        loc: SourcePointer,\n        want_dup_on_stack: bool,\n    ) -> ScopeResult<Option<UplevelSymbolResolution>> {\n        match self {\n            Self::ModuleRoot(r) => r.resolve_uplevel_symbol(name, dest, loc, want_dup_on_stack),\n            Self::ModuleChild(c) => c.resolve_uplevel_symbol(name, dest, loc, want_dup_on_stack),\n            Self::FunctionRoot(r) => r.resolve_uplevel_symbol(name, dest, loc, want_dup_on_stack),\n            Self::FunctionChild(c) => c.resolve_uplevel_symbol(name, dest, loc, want_dup_on_stack),\n        }\n    }\n}\n"
  },
  {
    "path": "docker/release/Dockerfile",
    "content": "# syntax=docker/dockerfile:1\nFROM ubuntu:24.04\n\n# Build arguments for Aria version and build timestamp\n# To build with a specific version, use:\n#   docker build --build-arg ARIA_VERSION=<version> --build-arg ARIA_BUILD_TIMESTAMP=<timestamp> -t aria:<version> .\n# Example:\n#   docker build --build-arg ARIA_VERSION=0.9.20251220 --build-arg ARIA_BUILD_TIMESTAMP=20251220123456 -t aria:0.9.20251220 .\nARG ARIA_VERSION=0.9.20251222\nARG ARIA_BUILD_TIMESTAMP=20251222174650\nARG ARIA_EXPECTED_SHA256=47cb8d9de3a2229f1a403e1c616679811f085e819c1743e263c16c2c2d001d50\n\nENV DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update \\\n    && apt-get install -y --no-install-recommends ca-certificates curl tar findutils \\\n    && rm -rf /var/lib/apt/lists/*\n\nRUN set -eux; \\\n    url=\"https://github.com/arialang/aria/releases/download/v${ARIA_VERSION}/aria-${ARIA_VERSION}-x86_64-unknown-linux-gnu-${ARIA_BUILD_TIMESTAMP}.tgz\"; \\\n    mkdir -p /usr/aria; \\\n    curl -fsSL \"$url\" -o /tmp/aria.tgz; \\\n    echo \"$ARIA_EXPECTED_SHA256 /tmp/aria.tgz\" | sha256sum -c -; \\\n    tar -xzf /tmp/aria.tgz -C /usr/aria; \\\n    rm -f /tmp/aria.tgz; \\\n    if [ ! -x /usr/aria/aria ]; then \\\n    aria_path=\"$(find /usr/aria -maxdepth 4 -type f -name aria -perm -111 | head -n1 || true)\"; \\\n    if [ -n \"$aria_path\" ] && [ \"$aria_path\" != \"/usr/aria/aria\" ]; then \\\n    ln -sf \"$aria_path\" /usr/aria/aria; \\\n    fi; \\\n    fi; \\\n    test -x /usr/aria/aria; \\\n    ln -sf /usr/aria/aria /usr/local/bin/aria\n\nCMD [\"bash\", \"-lc\", \"echo 'Aria is available in your environment. Start it by running \\\"aria\\\"\\n'; exec bash -i\"]\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta http-equiv=\"refresh\" content=\"0; url=https://arialang.github.io/\">\n    <link rel=\"canonical\" href=\"https://arialang.github.io/\">\n    <script>\n        window.location.replace(\"https://arialang.github.io/\");\n    </script>\n</head>\n\n<body>\n    If you are not redirected automatically, follow this <a href=\"https://arialang.github.io/\">link to the new\n        documentation site</a>.\n</body>\n\n</html>"
  },
  {
    "path": "examples/99bottles.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Lyrics {\n    type func new(n: Int) {\n        assert n > 0;\n        return alloc(This) {\n            .n = n,\n        };\n    }\n\n    func prettyprint() {\n        val suffix_n = this.n == 1 ? \"\" : \"s\";\n        val suffix_n_minus_1 = this.n == 2 ? \"\" : \"s\";\n        return \"{0} bottle{2} of beer on the wall, {0} bottle{2} of beer.\\nTake one down and pass it around, {1} bottle{3} of beer on the wall.\\n\".format(this.n, this.n-1, suffix_n, suffix_n_minus_1);\n    }\n}\n\nstruct Song {\n    type func new(n: Int) {\n        assert n > 0;\n        return alloc(This) {\n            .n = n,\n        };\n    }\n    \n    func iterator() {\n        return this;\n    }\n\n    func next() {\n        if this.n == 0 {\n            return Maybe::None;\n        }\n\n        val n = this.n;\n        this.n -= 1;\n\n        return Maybe::Some(Lyrics.new(n));\n    }\n}\n\nval song = Song.new(99);\nfor verse in song {\n    println(verse);\n}\n"
  },
  {
    "path": "examples/add_license_marker.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport File from aria.io.file;\nimport Path from aria.io.path;\nimport aria.iterator.mixin;\n\nval rust_license_comment=\"// SPDX-License-Identifier: Apache-2.0\";\nval aria_license_comment=\"# SPDX-License-Identifier: Apache-2.0\";\n\nstruct Checker {\n    type func new(ext: String, marker: String, check: Bool, exclusions: List) = alloc(This) { .ext, .marker, .check, .exclusions };\n\n    func should_exclude(path) {\n        val path = path.prettyprint();\n        return this.exclusions.any(|e| => path.contains(e));\n    }\n\n    operator()() {\n        val glob_pattern = \"**/*.{0}\".format(this.ext);\n        val glob_iterator = Path.glob(glob_pattern)!;\n        for file in glob_iterator {\n            if this.should_exclude(file) {\n                continue;\n            }\n\n            val line0 = File.open(file, File.OpenMode.new().read())!.readln();\n            if line0 != this.marker {\n                if this.check {\n                    println(\"[ERROR] file '{0}' missing license marker!\".format(file));\n                    return false;\n                } else {\n                    println(\"adding license marker to {0}\".format(file));\n                    val rest_of_file = File.open(file, File.OpenMode.new().read())!.read_all();\n                    File.open(file, File.OpenMode.new().write().truncate())!.write(\"{0}\\n{1}\".format(this.marker, rest_of_file));\n                }\n            }\n        }\n\n        return true;\n    }\n}\n\nfunc main(args) {\n    val check = false;\n    if args.len() == 1 && args[0] == \"--check\" {\n        check = true;\n    }\n\n    val aria_checker = Checker.new(\"aria\", aria_license_comment, check, [\"target/\"]);\n    val rust_checker = Checker.new(\"rs\", rust_license_comment, check, [\"target/\"]);\n\n    if !aria_checker() || !rust_checker() {\n        exit(1);\n    }\n\n    if check {\n        println(\"all files have license markers\");\n    }\n    exit(0);\n}\n"
  },
  {
    "path": "examples/advent_of_code_2024_day1.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Zip from aria.iterator.zip;\n\nval list1 = [3,4,2,1,3,3];\nval list2 = [4,3,5,3,9,3];\n\nassert list1.len() == list2.len();\n\nlist1.quicksort();\nlist2.quicksort();\n\nval z = Zip.new(list1, list2);\nval sum = 0;\nfor pair in z {\n    val distance = (pair[0] - pair[1]).abs();\n    sum += distance;\n}\n\nprintln(\"The total distance is {0}\".format(sum));\n"
  },
  {
    "path": "examples/advent_of_code_2024_day2.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Set from aria.structures.set;\nimport Range from aria.range.range;\n\nenum Direction {\n    case Increasing,\n    case Equal,\n    case Decreasing,\n}\n\nextension Direction {\n    func hash() {\n        match this {\n            case Increasing => { return 6037; },\n            case Equal => { return 4154; },\n            case Decreasing => { return 7889; }\n        }\n    }\n}\n\nfunc get_direction(a, b) {\n    if a > b {\n        return Direction::Increasing;\n    } elsif a == b {\n        return Direction::Equal;\n    } else {\n        return Direction::Decreasing;\n    }\n}\n\nfunc get_directions(nums) {\n    val directions = Set.new();\n    val idx = 0;\n    val bound = nums.len() - 2;\n    for idx in Range.from(0).through(bound) {\n        val a = nums[idx];\n        val b = nums[idx+1];\n        directions.set(get_direction(a,b));\n    }\n    return directions;\n}\n\nfunc get_max_delta(nums) {\n    val max_delta = -1;\n    val idx = 0;\n    val bound = nums.len() - 2;\n    for idx in Range.from(0).through(bound) {\n        val a = nums[idx];\n        val b = nums[idx+1];\n        val delta = (a-b).abs();\n        if delta > max_delta {\n            max_delta = delta;\n        }\n    }\n    return max_delta;\n}\n\nval inputs = [\n    [7,6,4,2,1],\n    [1,2,7,8,9],\n    [9,7,6,2,1],\n    [8,6,4,4,1],\n    [1,3,6,7,9],\n];\n\nfor input in inputs {\n    val directions = get_directions(input);\n    if directions.len() != 1 || directions.contains(Direction::Equal) {\n        println(\"Input {0} is unsafe (not always increasing/decreasing)\".format(input.join()));\n        continue;\n    }\n\n    val max_delta = get_max_delta(input);\n    if max_delta > 3 {\n        println(\"Input {0} is unsafe (levels change by more than 3)\".format(input.join()));\n        continue;\n    }\n\n    println(\"Input {0} is safe\".format(input.join()));\n}\n"
  },
  {
    "path": "examples/advent_of_code_2024_day3.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Regex from aria.string.regex;\n\nfunc find_all_mul_matches(str) {\n    val r = Regex.new(\"mul\\\\(\\\\d{1,3},\\\\d{1,3}\\\\)\");\n    val ret = [];\n    for m in r.matches(str) {\n        ret.append(m.value);\n    }\n    return ret;\n}\n\nfunc main() {\n    val input = \"xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))\";\n    val multiplications = find_all_mul_matches(input);\n    val total = 0;\n    for multiplication in multiplications {\n        val operands = multiplication.replace(\"mul(\", \"\").replace(\")\",\"\").split(\",\");\n        assert operands.len() == 2;\n        val op1 = Int.parse(operands[0])!;\n        val op2 = Int.parse(operands[1])!;\n        total += op1 * op2;\n    }\n    println(\"The total value is {0}\".format(total));\n}\n"
  },
  {
    "path": "examples/command_line_args.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nfor arg in cmdline_arguments() {\n    println(\"argument = '{0}'\".format(arg));\n}\n"
  },
  {
    "path": "examples/currency.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\nimport Map from aria.structures.map;\n\nenum FetchResult {\n    case Success(Map),\n    case Error(String)\n}\n\nfunc get_rates(currency: String) {\n    val url = \"https://open.er-api.com/v6/latest/{0}\".format(currency.uppercase());\n\n    val response = Request.new(url).get()?;\n    if response.status_code == 200 {\n        val data = JsonValue.parse(response.content)?.flatten();\n        match data.get(\"rates\") {\n            case Some(rates) => { return FetchResult::Success(rates); },\n            case None => { return FetchResult::Error(\"No rates found for {0}\".format(currency)); }\n        }\n    } else {\n        return FetchResult::Error(\"HTTP request failed with status code {0}\".format(response.status_code));\n    }\n}\n\nfunc convert(value, target, rates) {\n    return rates.get(target).apply(|x| => x * value);\n}\n\nfunc main() {\n    val args = cmdline_arguments();\n\n    if args.len() != 3 {\n        println(\"Usage: currency <value> <source_currency> <target_currency>\");\n        println(\"Example: currency 100 USD EUR\");\n        return Unit::unit;\n    }\n    \n    val value = Float.parse(args[0]);\n    if value.is_Err() {\n        println(\"Please provide a valid numeric value to convert.\");\n        return Unit::unit;\n    }\n    value = value!;\n\n    val source_currency = args[1].uppercase();\n    val target_currency = args[2].uppercase();\n\n    val fetched_rates = get_rates(source_currency);\n    val rates = Map.new();\n    match fetched_rates {\n        case Error(e) => {\n            println(\"Failed to fetch exchange rates: {0}\".format(e));\n            return Unit::unit;\n        }\n        case Success(r) => { rates = r; }\n    }\n\n    val converted_value = convert(value, target_currency, rates);\n    if converted_value.is_None() {\n        println(\"Conversion rate for {0} not found.\".format(target_currency));\n    } else {\n        println(\"{0} {1} is equivalent to {2} {3}.\".format(value, source_currency, converted_value.unwrap_Some(), target_currency));\n    }\n}\n"
  },
  {
    "path": "examples/dir.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Instant from aria.date.instant;\nimport Path from aria.io.path;\n\nfunc pad(n) {\n    if n < 10 {\n        return \"0{0}\".format(n);\n    } else {\n        return \"{0}\".format(n);\n    }\n}\n\nfunc run_over_dir(path: Path) {\n    val files_count = 0;\n    val dirs_count = 0;\n    val total_size = 0;\n\n    for entry in path.entries() {\n        val mod_time = entry\n                         .modified()\n                         .unwrap_or(Instant.new_with_local_timestamp(0));\n\n        val month = pad(mod_time.month);\n        val day = pad(mod_time.day);\n        val year = mod_time.year;\n        \n        val hour = mod_time.hour;\n        val minute = pad(mod_time.minute);\n        val am_pm = \"AM\";\n        if hour >= 12 {\n            am_pm = \"PM\";\n            if hour > 12 {\n                hour = hour - 12;\n            }\n        }\n        if hour == 0 {\n            hour = 12;\n        }\n\n        val date_str = \"{0}/{1}/{2}\".format(month, day, year);\n        val time_str = \"{0}:{1} {2}\".format(pad(hour), minute, am_pm);\n\n        if entry.is_directory() {\n            dirs_count += 1;\n\n            println(\"{0}  {1}       <DIR>          {2}\".format(\n                    date_str,\n                    time_str,\n                    entry.get_filename() ?? \"\"\n            ));\n        } else {\n            val size = entry.size();\n            match size {\n                case Err(_) => {\n                    size = 0;\n                }\n                case Ok(bytes) => {\n                    size = bytes;\n                }\n            }\n            total_size += size;\n            files_count += 1;\n\n            val size_str = \"{0}\".format(size);\n            val padding = \" \" * (14 - size_str.len());\n\n            println(\"{0}  {1}       {2}          {3}\".format(\n                date_str,\n                time_str,\n                size_str,\n                entry.get_filename() ?? \"\"\n            ));\n        }\n    }\n\n   println(\"\");\n   println(\"              {0} File(s)    {1} bytes\".format(files_count, total_size));\n   println(\"              {0} Dir(s)\".format(dirs_count));\n}\n\nfunc main() {\n    val args = cmdline_arguments();\n    for arg in args {\n        val arg_path = Path.new(arg);\n        if !arg_path.exists() || !arg_path.is_directory() {\n            println(\"{0} is not a valid directory; ignoring\".format(arg));\n            continue;\n        }\n\n        run_over_dir(arg_path);\n    }\n}\n"
  },
  {
    "path": "examples/fibonacci.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc fibonacci(n) {\n    if n == 0 {\n        return 0;\n    } elsif n == 1 {\n        return 1;\n    } else {\n        return fibonacci(n-1) + fibonacci(n-2);\n    }\n}\n\nprintln(fibonacci(28));\n"
  },
  {
    "path": "examples/fibonacci_memoized.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nstruct Fibonacci {\n    type func new() {\n        return alloc(This) {\n            .cache = Map.new(){[0] = 0, [1] = 1},\n        };\n    }\n\n    func eval(n) {\n        match this.cache.get(n) {\n            case Some(result) => { return result; }\n        } else {\n            val result = this.eval(n-1) + this.eval(n-2);\n            this.cache[n] = result;\n            return result;\n        }\n    }\n    \n    func fibonacci(n) {\n        return this.eval(n);\n    }\n}\n\nval f = Fibonacci.new();\nprintln(f.fibonacci(28));\n"
  },
  {
    "path": "examples/fizzbuzz.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nextension Int {\n    func is_divisible_by(n: Int) {\n        return (this % n) == 0;\n    }\n\n    func to_fizzbuzz_string() {\n        val div_by_3 = this.is_divisible_by(3);\n        val div_by_5 = this.is_divisible_by(5);\n        if div_by_3 && div_by_5 {\n            return \"FizzBuzz\";\n        } elsif div_by_3 {\n            return \"Fizz\";\n        } elsif div_by_5 {\n            return \"Buzz\";\n        } else {\n            return this;\n        }\n    }\n}\n\nfor n in Range.from(1).through(20) {\n    println(\"{0} -> {1}\".format(n, n.to_fizzbuzz_string()));\n}\n"
  },
  {
    "path": "examples/github_user.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\n\nval whoami = \"egranata\";\n\nfunc main() {\n    val request = Request.new(\"https://api.github.com/users/{0}\".format(whoami));\n    request.headers[\"User-Agent\"] = \"AriaLang/1.0\";\n    val response = request.get()!;\n\n    if response.status_code == 200 {\n        val user_data = JsonValue.parse(response.content)!.flatten();\n        println(\"User {1} has {0} public repositories.\".format(user_data[\"public_repos\"], whoami));\n    } else {\n        println(\"Failed to fetch user data. Status: {0}\".format(response.status_code));\n    }\n}\n"
  },
  {
    "path": "examples/hello.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nprintln('Hello World!');\n"
  },
  {
    "path": "examples/parser.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\nimport aria.string.classes;\n\nenum Token {\n    case Number(Int),\n    case Identifier(String),\n    case Plus,\n    case Minus,\n    case Star,\n    case Slash,\n    case LeftParen,\n    case RightParen,\n    case EOF,\n}\n\nextension Token {\n    func prettyprint() {\n        match this {\n            case Number(n) => { return prettyprint(n); },\n            case Identifier(s) => { return s; },\n            case Plus => { return \"+\"; },\n            case Minus => { return \"-\"; },\n            case Star => { return \"*\"; },\n            case Slash => { return \"/\"; },\n            case LeftParen => { return \"(\"; },\n            case RightParen => { return \")\"; },\n            case EOF => { return \"<eof>\"; },\n        }\n    }\n}\n\nstruct Lexer {\n    struct InvalidCharacter {\n        type func new(c) {\n            return alloc(This) {\n                .c = c,\n            };\n        }\n\n        func prettyprint() {\n            return \"Invalid character: '{0}'\".format(this.c);\n        }\n    }\n\n    type func new(text) {\n        return alloc(This) {\n            .text = text,\n            .pos = 0,\n        };\n    }\n\n    func current() {\n        return this.text[this.pos];\n    }\n\n    func eof() {\n        return this.pos >= this.text.len();\n    }\n\n    func advance() {\n        this.pos += 1;\n    }\n\n    func whitespace() {\n        while !this.eof() {\n            val c = this.current();\n            if c.is_whitespace() {\n                this.advance();\n            } else {\n                break;\n            }\n        }\n    }\n\n    func identifier() {\n        val id_str = \"\";\n        while !this.eof() {\n            val c = this.current();\n            if !c.is_alphanumeric() {\n                break;\n            } else {\n                id_str += c;\n                this.advance();\n            }\n        }\n\n        return Token::Identifier(id_str);\n    }\n\n    func number() {\n        val num_str = \"\";\n        while !this.eof() {\n            val c = this.current();\n            if !c.is_digit() {\n                break;\n            } else {\n                num_str += c;\n                this.advance();\n            }\n        }\n\n        return Token::Number(Int.parse(num_str)!);\n    }\n\n    func next() {\n        while !this.eof() {\n            if this.current().is_whitespace() {\n                this.whitespace();\n            }\n \n            if this.current().is_digit() {\n                return this.number();\n            }\n\n            if this.current().is_letter() {\n                return this.identifier();\n            }\n            \n            if this.current() == \"+\" {\n                this.advance();\n                return Token::Plus;\n            }\n\n            if this.current() == \"-\" {\n                this.advance();\n                return Token::Minus;\n            }\n\n            if this.current() == \"*\" {\n                this.advance();\n                return Token::Star;\n            }\n\n            if this.current() == \"/\" {\n                this.advance();\n                return Token::Slash;\n            }\n\n            if this.current() == \"(\" {\n                this.advance();\n                return Token::LeftParen;\n            }\n\n            if this.current() == \")\" {\n                this.advance();\n                return Token::RightParen;\n            }\n\n            throw Lexer.InvalidCharacter.new(this.current());\n        }\n\n        return Token::EOF;\n    }\n}\n\nstruct Ast {\n    struct Identifier {\n        type func new(name: String) {\n            return alloc(This) {\n                .name = name,\n            };\n        }\n\n        func prettyprint() {\n            return \"Identifier({0})\".format(this.name);\n        }\n\n        func eval(identifiers) {\n            return identifiers[this.name];\n        }\n    }\n\n    struct Number {\n        type func new(v: Int) {\n            return alloc(This) {\n                .value = v,\n            };\n        }\n\n        func prettyprint() {\n            return \"Number({0})\".format(this.value);\n        }\n\n        func eval(_) {\n            return this.value;\n        }\n    }\n\n    struct BinaryOperation {\n        enum Operator {\n            case Add,\n            case Sub,\n            case Mul,\n            case Div,\n        }\n    }\n}\n\nextension Ast.BinaryOperation {\n    type func new(left, right, op: Ast.BinaryOperation.Operator) {\n        return alloc(This) {\n            .left = left,\n            .op = op,\n            .right = right,\n        };\n    }\n\n    func prettyprint() {\n        return \"BinOp(({0}) {1} ({2}))\".format(this.left, this.op, this.right);\n    }\n\n    func eval(identifiers) {\n        val left = this.left.eval(identifiers);\n        val right = this.right.eval(identifiers);\n\n        match this.op {\n            case Add => { return left + right; },\n            case Sub => { return left - right; },\n            case Mul => { return left * right; },\n            case Div => { return left / right; },\n        } else {\n            assert(false);\n        }\n    }\n}\n\nextension Ast.BinaryOperation.Operator {\n    type func from(src: Token) {\n        match src {\n            case Plus => { return This::Add; },\n            case Minus => { return This::Sub; },\n            case Star => { return This::Mul; },\n            case Slash => { return This::Div; },\n        } else {\n            assert(false);\n        }\n    }\n\n    func prettyprint() {\n        match this {\n            case Add => { return \"+\"; },\n            case Sub => { return \"-\"; },\n            case Mul => { return \"*\"; },\n            case Div => { return \"/\"; },\n        }\n    }\n}\n\nstruct Parser {\n    struct UnexpectedToken {\n        func prettyprint() {\n            return \"Unexpected token encountered\";\n        }\n    }\n    type func new(lexer: Lexer) {\n        return alloc(This) {\n            .lexer = lexer,\n            .current_token = lexer.next(),\n        };\n    }\n\n    func eat(f) {\n        if f(this.current_token) {\n            this.current_token = this.lexer.next();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    func factor() {\n        val token = this.current_token;\n        if this.eat(|t| => t.is_Number()) {\n            return Ast.Number.new(token.unwrap_Number());\n        } elsif this.eat(|t| => t.is_LeftParen()) {\n            val node = this.expr();\n            assert (this.eat(|t| => t.is_RightParen()));\n            return node;\n        } elsif this.eat(|t| => t.is_Identifier()) {\n            return Ast.Identifier.new(token.unwrap_Identifier());\n        } else {\n            throw alloc(Parser.UnexpectedToken);\n        }\n    }\n\n    func term() {\n        val node = this.factor();\n        while true {\n            val op = this.current_token;\n            if this.eat(|t| => t.is_Star() || t.is_Slash()) {\n                op = Ast.BinaryOperation.Operator.from(op);\n                node = Ast.BinaryOperation.new(node, this.factor(), op);\n            } else {\n                return node;\n            }\n        }\n    }\n\n    func expr() {\n        val node = this.term();\n        while true {\n            val op = this.current_token;\n            if this.eat(|t| => t.is_Plus() || t.is_Minus()) {\n                op = Ast.BinaryOperation.Operator.from(op);\n                node = Ast.BinaryOperation.new(node, this.term(), op);\n            } else {\n                return node;\n            }\n        }\n    }\n\n    func parse() {\n        return this.expr();\n    }\n}\n\nfunc main() {\n    val identifiers = Map.new() {\n        [\"answer\"] = 42,\n    };\n\n    val input = \"answer + 4 * (5 - 7 / 2)\";\n    val lxr = Lexer.new(input);\n    val parser = Parser.new(Lexer.new(input));\n    val ast = parser.parse();\n    println(\"{0} -> {1}\".format(ast, ast.eval(identifiers)));\n}\n"
  },
  {
    "path": "examples/peano.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nenum Peano {\n    case Zero,\n    case Succ(Peano),\n}\n\nextension Peano {\n    func prettyprint() {\n        match this {\n            case Zero => { return \"\"; },\n            case Succ(x) => { return \"+\" + x.prettyprint(); },\n        }\n    }\n\n    func double() {\n        match this {\n            case Zero => { return Peano::Zero; },\n            case Succ(x) => { return Peano::Succ(Peano::Succ(x.double())); },\n        }\n    }\n\n    func quadruple() {\n        return this.double().double();\n    }\n\n    func succ() {\n        return Peano::Succ(this);\n    }\n}\n\nval three = Peano::Zero.succ().succ().succ();\nval twelve = three.quadruple();\n\nprintln(\"{0}\".format(twelve));\n"
  },
  {
    "path": "examples/pi.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc calc_pi() {\n    val lasts = 0;\n    val t = 3.0f;\n    val s = 3;\n    val n = 1;\n    val na = 0;\n    val d = 0;\n    val da = 24;\n    while s != lasts {\n        lasts = s;\n        n = n + na;\n        na = na + 8;\n        d = d + da;\n        da = da + 32;\n        t = (t * n) / d;\n        s = s + t;\n    }\n    return s;\n}\n\nprintln(\"pi = {0}\".format(calc_pi()));\n"
  },
  {
    "path": "examples/sieve.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n# Based on https://github.com/PlummersSoftwareLLC/Primes/blob/drag-race/PrimeWren/solution_1/primes.wren\n\nimport Map from aria.structures.map;\n\nval DICT = Map.new() {\n    [10] = 4,\n    [100] = 25,\n    [1000] = 168,\n    [10000] = 1229,\n    [100000] = 9592,\n    [1000000] = 78498,\n    [10000000] = 664579,\n    [100000000] = 5761455,\n    [1000000000] = 50847534,\n    [10000000000] = 455052511,\n};\n\nextension Int {\n    func sqrt() {\n        val x = this;\n        val y = (x + 1) / 2;\n\n        while y < x {\n            x = y;\n            y = (x + this / x) / 2;\n        }\n\n        return x;\n    }\n}\n\nstruct Sieve {\n    type func new(size: Int) = alloc(This) {\n        .size,\n        .bits = List.filled(false, size),\n    };\n\n    func run() {\n        val bits = this.bits;\n        val size = this.size;\n\n        val factor = 3;\n        val q = size.sqrt();\n\n        while factor <= q {\n            val num = factor;\n            while num < size {\n                if !bits[num] {\n                    factor = num;\n                    break;\n                }\n\n                num += 2;\n            }\n\n            val num2 = factor * factor;\n            while num2 < size {\n                bits[num2] = true;\n                num2 += factor * 2;\n            }\n\n            factor += 2;\n        }\n    }\n\n    func count_primes() {\n        val count = 1;\n        val num = 3;\n        while num < this.size {\n            if !this.bits[num] {\n                count += 1;\n            }\n            num += 2;\n        }\n\n        return count;\n    }\n\n    func validate() = DICT.contains(this.size) && DICT[this.size] == this.count_primes();\n\n    func print_results(show, duration, passes) {\n        if show {\n            print(\"2, \");\n            val count = 1;\n            val num = 3;\n            while num < this.size {\n                if !this.bits[num] {\n                    \"{0}, \".printf(num);\n                    count += 1;\n                }\n                num += 2;\n            }\n            println(\"\");\n        }\n\n        assert this.validate();\n\n        \"egranata;{0};{1:.2};1;algorithm=base,faithful=yes\\n\".printf(passes, duration/1000.0);\n    }\n}\n\nval passes = 0;\nval start_time = now();\n\nwhile true {\n    val sieve = Sieve.new(1000000);\n    sieve.run();\n\n    passes += 1;\n    val duration = now() - start_time;\n    if duration >= 5000 {\n        sieve.print_results(false, duration, passes);\n        break;\n    }\n}\n"
  },
  {
    "path": "examples/string_escapes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Color, ColorScheme from aria.system.coloring;\n\nprintln(\"Hello {0}, this is an {1} {2}\".format(\n        \"world\".red(),\n        \"example\".blue().white_bg(),\n        \"program\".with_bold()\n));\n\nval color_scheme = ColorScheme.new().with_foreground_color(Color::BrightMagenta).with_background_color(Color::BrightWhite).with_bold(true);\n\nprintln(\"This is yet another example string\".with_style(color_scheme));\n\nprintln(\"And this one is {0} unformatted.\".format(\"mostly\".with_foreground_color(Color::RGB(Color.RGB.new(255,165,0)))));\n\nprintln(\"And this one uses {0} background color\".format(\"hexadecimal\".with_background_color(Color::RGB(Color.RGB.new_with_hex_string(\"#c3e91c\")!))));\n"
  },
  {
    "path": "lib/aria/core/arity.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nstruct Arity {\n    enum UpperBound {\n        case Bounded(Int),\n        case Varargs,\n\n        func prettyprint() {\n            match this {\n                case Bounded(n) => {\n                    return \"up to {0}\".format(n);\n                },\n                case Varargs => {\n                    return \"varargs\";\n                },\n            }\n        }\n    }\n\n    # this type is generally allocated by the Aria VM directly, not by user code\n    # new() is not going to be called\n    type func new() {\n        return alloc(This) {\n            .min = 0,\n            .max = This.UpperBound::Varargs,\n            .has_receiver = false,\n        };\n    }\n\n    func prettyprint() {\n        return \"min: {0} (implicit receiver: {2}), max: {1}\".format(this.min, this.max, this.has_receiver);\n    }\n\n    func is_Varargs() {\n        return this.max.is_Varargs();\n    }\n\n    func can_call_with_argc(argc: Int) {\n        if argc < this.min {\n            return false;\n        }\n        match this.max {\n            case Bounded(n) => {\n                return argc <= n;\n            },\n            case Varargs => {\n                return true;\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/bool.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nextension Bool {\n    func hash() {\n        return this ? 4093 : 7877;\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/box.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nfunc Box() {\n    struct Box {}\n    return alloc(Box);\n}\n"
  },
  {
    "path": "lib/aria/core/builtin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nimport aria.core.runtime_error;\n\nimport aria.core.arity;\n\nimport aria.core.bool;\n\nimport Box from aria.core.box;\n\nimport aria.core.float;\n\nimport aria.core.int;\n\nimport aria.core.list;\n\nimport aria.core.maybe;\n\nimport aria.core.result;\n\nimport aria.core.string;\n\nimport Nothing from aria.core.nothing;\n\nimport aria.core.unimplemented;\n\nimport aria.core.unit;\n"
  },
  {
    "path": "lib/aria/core/float.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nfunc char_to_int(c: String) {\n    match c {\n        == \"0\" => { return 0; },\n        == \"1\" => { return 1; },\n        == \"2\" => { return 2; },\n        == \"3\" => { return 3; },\n        == \"4\" => { return 4; },\n        == \"5\" => { return 5; },\n        == \"6\" => { return 6; },\n        == \"7\" => { return 7; },\n        == \"8\" => { return 8; },\n        == \"9\" => { return 9; },\n    } else {\n        return Maybe::None;\n    }\n}\n\nextension Float {\n    type val pi = 3.14159265358979323846f;\n    type val e =  2.71828182845904523536f;\n    type val π = Float.pi;\n    type val phi = 1.618033988749895f;\n    type val φ = Float.phi;\n\n    func abs() {\n        return this >= 0 ? this : -this;\n    }\n\n    struct DomainError {\n        type func new(msg: String) {\n            return alloc(This) {\n                .msg = msg\n            };\n        }\n\n        instance func prettyprint() {\n            return \"floating-point domain error: {0}\".format(this.msg);\n        }\n    }\n\n    func sqrt() {\n        match this {\n            == 0 => { return 0.0f; },\n            == 1 => { return 1.0f; },\n            < 0 => { throw Float.DomainError.new(\"square root undefined for negative values\"); },\n        }\n\n        val ε = 0.000000000001f;\n\n        val guess = this / 2;\n\n        val i = 0;\n        val n = 1000;\n        while i < n {\n            i = i + 1;\n            val next_guess = (guess + this / guess) / 2;\n            if (next_guess - guess).abs() < ε {\n                return next_guess;\n            } else {\n                guess = next_guess;\n            }\n        }\n\n        return guess;\n    }\n\n    type func parse(s: String) {\n        if s.len() == 0 || s == \"-\" || s == \".\" {\n            return Result::Err(\"invalid float format\");\n        }\n        \n        val ret = 0.0f;\n        val i = 0;\n        val sign = 1;\n        val decimal_found = false;\n        val decimal_factor = 0.1f;\n\n        val s: List = s.chars();\n\n        if s[0] == \"-\" {\n            i = 1;\n            sign = -1;\n        }\n\n        while i < s.len() {\n            val chr = s[i];\n            if chr == \"e\" || chr == \"E\" {\n                break;\n            }\n            if chr == \".\" {\n                if decimal_found {\n                    return Result::Err(\"duplicate decimal point\");\n                }\n                decimal_found = true;\n            } else {\n                val digit = char_to_int(chr);\n                if digit == Maybe::None {\n                    return Result::Err(\"invalid float digit: \" + chr);\n                }\n                if decimal_found {\n                    ret = ret + digit * decimal_factor;\n                    decimal_factor = decimal_factor / 10;\n                } else {\n                    ret = ret * 10 + digit;\n                }\n            }\n            i += 1;\n        }\n\n        ret = sign * ret;\n\n        if i < s.len() {\n            i += 1;\n            if i >= s.len() {\n                return Result::Err(\"missing exponent\");\n            }\n\n            val exp_sign = 1;\n            if s[i] == \"-\" {\n                exp_sign = -1;\n                i += 1;\n            } elsif s[i] == \"+\" {\n                i += 1;\n            }\n\n            if i >= s.len() {\n                return Result::Err(\"missing exponent digits\");\n            }\n\n            val exp_value = 0;\n            while i < s.len() {\n                val digit = char_to_int(s[i]);\n                if digit == Maybe::None {\n                    return Result::Err(\"invalid float exponent digit: \" + s[i]);\n                }\n                exp_value = exp_value * 10 + digit;\n                i += 1;\n            }\n\n            val exp = exp_sign * exp_value;\n            val factor = 1.0f;\n            val j = 0;\n            val limit = exp < 0 ? -exp : exp;\n            while j < limit {\n                factor = factor * 10;\n                j += 1;\n            }\n\n            ret = exp < 0 ? ret / factor : ret * factor;\n        }\n        \n        return Result::Ok(ret);\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/int.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nextension Int {\n    func hash() {\n        return this;\n    }\n\n    func abs() {\n        return this >= 0 ? this : -this;\n    }\n\n    func float() {\n        return this + 0.0f;\n    }\n\n    type func parse(s: String) {\n        val index: Int = 0;\n\n        val sign: Int = 1;\n        if s.has_prefix(\"-\") {\n            sign = -1;\n            index = 1;\n        } elsif s.has_prefix(\"+\") {\n            index = 1;\n        }\n        if index > 0 {\n            s = s.substring(index, s.len());\n            index = 0;\n        }\n\n        val base: Int = 10;\n        if s.has_prefix(\"0x\") || s.has_prefix(\"0X\") {\n            index = 2;\n            base = 16;\n        } elsif s.has_prefix(\"0b\") || s.has_prefix(\"0B\") {\n            index = 2;\n            base = 2;\n        } elsif s.has_prefix(\"0o\") || s.has_prefix(\"0O\") {\n            index = 2;\n            base = 8;\n        }\n        if index > 0 {\n            s = s.substring(index, s.len());\n            index = 0;\n        }\n\n        if s == \"\" {\n            return Result::Err(\"empty integer string\");\n        }\n\n        match Int.parse_radix(s, base) {\n            case Ok(value) => {\n                return Result::Ok(sign * value);\n            },\n            case Err(e) => {\n                return Result::Err(e);\n            },\n        }\n    }\n\n    type func parse_radix(s: String, base: Int) {\n        if base < 2 || base > 36 {\n            return Result::Err(\"invalid radix\");\n        }\n\n        if s.len() == 0 {\n            return Result::Err(\"empty integer string\");\n        }\n\n        val s: List = s.chars();\n\n        val ret: Int = 0;\n        val i: Int = 0;\n\n        while i < s.len() {\n            val chr = s[i];\n            val digit = chr.encoding();\n            match digit {\n                >= 48 and <= 57 => {\n                    # decimal digits\n                    if (digit - 48) >= base {\n                        return Result::Err(\"invalid integer digit: \" + chr);\n                    }\n                    digit = digit - 48;\n                },\n                >= 65 and <= 90 => {\n                    # uppercase letters\n                    if (digit - 65 + 10) >= base {\n                        return Result::Err(\"invalid integer digit: \" + chr);\n                    }\n                    digit = digit - 65 + 10;\n                },\n                >= 97 and <= 122 => {\n                    # lowercase letters\n                    if (digit - 97 + 10) >= base {\n                        return Result::Err(\"invalid integer digit: \" + chr);\n                    }\n                    digit = digit - 97 + 10;\n                },\n            } else {\n                return Result::Err(\"invalid integer digit: \" + chr);\n            }\n            ret = ret * base + digit;\n            i += 1;\n        }\n\n        return Result::Ok(ret);\n    }\n}\n\nextension Int {\n    struct DomainError {\n        type func new(msg: String) {\n            return alloc(This) {\n                .msg = msg\n            };\n        }\n\n        instance func prettyprint() {\n            return \"integer domain error: {0}\".format(this.msg);\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/list.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nimport Box from aria.core.box;\n\nextension List {\n    func repeat(n: Int) {\n        if n <= 0 { return []; }\n        if n == 1 { return this; }\n        val ret = this;\n        while n > 1 {\n            ret = ret + this;\n            n -= 1;\n        }\n        return ret;\n    }\n\n    operator *(rhs: Int) {\n        return this.repeat(rhs);\n    }\n\n    reverse operator *(lhs: Int) {\n        return this.repeat(lhs);\n    }\n\n    func prettyprint() {\n        return \"[\" + this.join() + \"]\";\n    }\n\n    func join(sep=\", \") = sep.join(this);\n\n    func contains(x) {\n        for item in this {\n            if item == x {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    type func from_function(f, n: Int) {\n        if n <= 0 {\n            return [];\n        }\n    \n        val ret = List.new_with_capacity(n);\n        val i = 0;\n        while i < n {\n            ret.append(f(i));\n            i = i + 1;\n        }\n\n        return ret;\n    }\n\n    type func filled(x, n: Int) {\n        if n <= 0 {\n            return [];\n        }\n\n        val ret = List.new_with_capacity(n);\n        val i = 0;\n        while i < n {\n            ret.append(x);\n            i = i + 1;\n        }\n\n        return ret;\n    }\n\n    operator ==(rhs: List) {\n        if rhs.len() != this.len() {\n            return false;\n        }\n\n        val idx = 0;\n        while idx < this.len() {\n            val this_idx = this[idx];\n            val rhs_idx = rhs[idx];\n\n            if this_idx != rhs_idx {\n                return false;\n            }\n\n            idx += 1;\n        }\n\n        return true;\n    }\n\n    operator +(rhs: List) {\n        val ret = [];\n        for item in this {\n            ret.append(item);\n        }\n        for item in rhs {\n            ret.append(item);\n        }\n        return ret;\n    }\n\n    struct ListIterator {\n        type func new(l: List) {\n            return alloc(This){\n                .list = l,\n                .len = l.len(),\n                .index = 0,\n            };\n        }\n\n        func next() {\n            if this.index == this.len {\n                return Maybe::None;\n            } else {\n                val v = this.list[this.index];\n                this.index = this.index + 1;\n                return Maybe::Some(v);\n            }\n        }\n    }\n\n    func iterator() {\n        return List.ListIterator.new(this);\n    }\n\n    func quicksort_with_comparator(f) {\n        this.qks_helper(0, this.len() - 1, f);\n    }\n\n    func quicksort() {\n        this.quicksort_with_comparator(|x,y| => x < y);\n    }\n\n    func qks_helper(left, right, f) {\n        if left >= right {\n            return 0;\n        }\n        val pivotIndex = this.partition(left, right, f);\n        this.qks_helper(left, pivotIndex - 1, f);\n        this.qks_helper(pivotIndex + 1, right, f);\n    }\n\n    func partition(left, right, f) {\n        val pivot = this[right];\n        val i = left;\n        val j = left;\n        while j < right {\n            if f(this[j], pivot) {\n                val temp = this[i];\n                this[i] = this[j];\n                this[j] = temp;\n                i += 1;\n            }\n            j += 1;\n        }\n        val temp = this[i];\n        this[i] = this[right];\n        this[right] = temp;\n        return i;\n    }\n\n    func binary_search(target) {\n        return this.bs_helper(target, 0, this.len() - 1);\n    }\n\n    func bs_helper(target, left, right) {\n        if left > right {\n            return Maybe::None;\n        }\n        val mid = (left + right) / 2;\n        if this[mid] == target {\n            return Maybe::Some(mid);\n        } elsif this[mid] < target {\n            return this.bs_helper(target, mid + 1, right);\n        } else {\n            return this.bs_helper(target, left, mid - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/maybe.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nextension Maybe {\n    func apply(f) {\n        match this {\n            case Some(x) => { return Maybe::Some(f(x)); },\n            case None => { return Maybe::None; }\n        }\n    }\n\n    func hash() {\n        match this {\n            case Some(x) => { return x.hash(); },\n        } else {\n            return 0;\n        }\n    }\n\n    func unwrap_or(els) = this ?? els;\n\n    func prettyprint() {\n        match this {\n            case None => {\n                return \"None\";\n            },\n            case Some(value) => {\n                return \"Some({0})\".format(value);\n            }\n        }\n    }\n\n    # these helpers are built by the Aria compiler, but since Maybe is a builtin type we need to provide them here\n    func is_Some() {\n        match this {\n            case Some(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n    func is_None() {\n        match this {\n            case None => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n    func unwrap_Some() {\n        match this {\n            case Some(value) => { return value; },\n        } else {\n            assert false;\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/nothing.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nenum Nothing {}\n"
  },
  {
    "path": "lib/aria/core/result.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nfunc ok(v)  { return Result::Ok(v); }\nfunc err(e) { return Result::Err(e); }\n\nextension Result {\n    # these helpers are built by the Aria compiler, but since Result is a builtin type we need to provide them here\n    func is_Ok() {\n        match this {\n            case Ok(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n    func is_Err() {\n        match this {\n            case Err(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n    func unwrap_Ok() {\n        match this {\n            case Ok(value) => { return value; },\n        } else {\n            assert false;\n        }\n    }\n\n    func unwrap_Err() {\n        match this {\n            case Err(value) => { return value; },\n        } else {\n            assert false;\n        }\n    }\n}\n\nextension Result {\n    func apply(f) {\n        match this {\n            case Ok(x) => { return Result::Ok(f(x)); },\n            case Err(e) => { return Result::Err(e); }\n        }\n    }\n\n    type func new_with_maybe(m: Maybe) {\n        match m {\n            case Some(v) => { return ok(v); }\n            case None => { return err(Unit.new()); }\n        }\n    }\n\n    type func new_with_try(f) {\n        try {\n            return ok(f());\n        } catch e {\n            return err(e);\n        }\n    }\n\n    func or_throw() {\n        match this {\n            case Ok(v) => { return v; }\n            case Err(e) => { throw e; }\n        }\n    }\n\n    func prettyprint() {\n        match this {\n            case Ok(v)  => { return \"Ok({0})\".format(v); },\n            case Err(e) => { return \"Err({0})\".format(e); }\n        }\n    }\n\n    func apply(f) {\n        match this {\n            case Ok(v)  => { return Result::Ok(f(v)); },\n            case Err(e) => { return Result::Err(e); }\n        }\n    }\n\n    func unwrap_or(els) = this ?? els;\n\n    func hash() {\n        match this {\n            case Ok(v)  => { return v.hash(); },\n            case Err(e) => { return e.hash(); }\n        }\n    }\n}\n\nextension Maybe {\n    type func new_with_result(r: Result) {\n        match r {\n            case Ok(v) => { return Maybe::Some(v); }\n            case Err(_) => { return Maybe::None; }\n        }\n    }\n}\n\nextension Result {\n    # what this does:\n    # if the object is a participant in the \"try protocol\", it will call _op_try_view()\n    # if the result is a Maybe or a Result, it will return that object up to the VM;\n    # if the result is something else, or the object does not implement the protocol, it will return Result::Ok(x)\n    # the TRY_UNWRAP_PROTOCOL bytecode will then inspect this value and:\n    # if it's a Result::Ok(x), it will push \"x\" onto the stack;\n    # if it's a Result::Err(e), it will RETURN Err(e) from the current function\n    # for anything else, it will raise a type error\n    type func try_unwrap_protocol(x) {\n        func process_value(x) {\n            match x {\n                isa Maybe => { return x; },\n                isa Result => { return x; },\n            } else {\n                return Result::Ok(x);\n            }\n        }\n\n        if hasattr(x, \"_op_try_view\") {\n            return process_value(x._op_try_view());\n        } else {\n            return process_value(x);\n        }\n    }\n}\n\nextension Result {\n    func _op_try_view() = this;\n}\n\nextension Maybe {\n    func _op_try_view() = this;\n}\n"
  },
  {
    "path": "lib/aria/core/runtime_error.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nextension RuntimeError.ArgcMismatch {\n    func prettyprint() = \"argument count mismatch, {0} expected, {1} actual\".format(this.expected, this.actual);\n}\n\nextension RuntimeError {\n    # helpers that are normally provided by the Aria compiler but we must define them here for a builtin type\n    func is_DivisionByZero() {\n        match this {\n            case DivisionByZero => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n    func is_EnumWithoutPayload() {\n        match this {\n            case EnumWithoutPayload => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n    func is_IndexOutOfBounds() {\n        match this {\n            case IndexOutOfBounds(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n    func unwrap_IndexOutOfBounds() {\n        match this {\n            case IndexOutOfBounds(x) => { return x; },\n        } else {\n            assert false;\n        }\n    }\n\n    func is_MismatchedArgumentCount() {\n        match this {\n            case MismatchedArgumentCount(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n    func unwrap_MismatchedArgumentCount() {\n        match this {\n            case MismatchedArgumentCount(x) => { return x; },\n        } else {\n            assert false;\n        }\n    }\n\n    func is_NoSuchCase() {\n        match this {\n            case NoSuchCase(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n    func unwrap_NoSuchCase() {\n        match this {\n            case NoSuchCase(x) => { return x; },\n        } else {\n            assert false;\n        }\n    }\n\n    func is_NoSuchIdentifier() {\n        match this {\n            case NoSuchIdentifier(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n    func unwrap_NoSuchIdentifier() {\n        match this {\n            case NoSuchIdentifier(x) => { return x; },\n        } else {\n            assert false;\n        }\n    }\n\n    func is_OperationFailed() {\n        match this {\n            case OperationFailed(_) => { return true; },\n        } else {\n            return false;\n        }\n    }\n    func unwrap_OperationFailed() {\n        match this {\n            case OperationFailed(x) => { return x; },\n        } else {\n            assert false;\n        }\n    }\n\n    func is_UnexpectedType() {\n        match this {\n            case UnexpectedType => { return true; },\n        } else {\n            return false;\n        }\n    }\n\n}\n\nextension RuntimeError {\n    func prettyprint() {\n        match this {\n            case DivisionByZero => {\n                return \"division by zero\";\n            },\n            case EnumWithoutPayload => {\n                return \"enum case has no payload\";\n            },\n            case IndexOutOfBounds(n) => {\n                return \"index {0} is out of bounds\".format(n);\n            },\n            case MismatchedArgumentCount(m) => {\n                return m.prettyprint();\n            },\n            case NoSuchCase(s) => {\n                return \"case '{0}' not found\".format(s);\n            },\n            case NoSuchIdentifier(s) => {\n                return \"identifier '{0}' not found\".format(s);\n            },\n            case OperationFailed(s) => {\n                return \"operation failed: {0}\".format(s);\n            }\n            case UnexpectedType => {\n                return \"unexpected type\";\n            }\n        }\n\n        return \"unprintable error\";\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/string.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\n# this is conceptually the same as what's in aria.string.classes\n# but we don't want to import from the core builtin library, so\n# the duplication of this rather trivial code is acceptable\nfunc is_digit(s: String) {\n    match s {\n        == \"0\" => { return true; },\n        == \"1\" => { return true; },\n        == \"2\" => { return true; },\n        == \"3\" => { return true; },\n        == \"4\" => { return true; },\n        == \"5\" => { return true; },\n        == \"6\" => { return true; },\n        == \"7\" => { return true; },\n        == \"8\" => { return true; },\n        == \"9\" => { return true; },\n    } else {\n        return false;\n    }\n}\n\nextension String {\n    operator[](index: Int) {\n        if index < 0 {\n            index += this.len();\n        }\n        return this._get_at(index);\n    }\n}\n\nextension String {\n    struct EncodingError {\n        type func new(msg: String) {\n            return alloc(This) {\n                .msg = msg\n            };\n        }\n\n        instance func prettyprint() {\n            return \"encoding error: {0}\".format(this.msg);\n        }\n    }\n\n    func repeat(n: Int) {\n        if n <= 0 { return \"\"; }\n        if n == 1 { return this; }\n        val ret = this;\n        while n > 1 {\n            ret = ret + this;\n            n -= 1;\n        }\n        return ret;\n    }\n\n    operator *(rhs: Int) {\n        return this.repeat(rhs);\n    }\n\n    reverse operator *(lhs: Int) {\n        return this.repeat(lhs);\n    }\n\n    func trim() {\n        return this.trim_head().trim_tail();\n    }\n\n    func prettyprint() {\n        return this;\n    }\n\n    func format(...) {\n        return this._format_impl(varargs);\n    }\n\n    func _format_impl(varargs) {\n        val ret = \"\";\n        val chars = this.chars();\n        val len = this.len();\n        val idx = 0;\n\n        while idx < len {\n            val c = chars[idx];\n\n            if c == \"{\" && idx + 1 < len && chars[idx + 1] == \"{\" {\n                ret += \"{\";\n                idx += 2;\n                continue;\n            }\n\n            if c == \"}\" && idx + 1 < len && chars[idx + 1] == \"}\" {\n                ret += \"}\";\n                idx += 2;\n                continue;\n            }\n\n            if c == \"{\" {\n                idx += 1;\n                val num_str = \"\";\n                val style_str = \"\";\n                val has_style = false;\n                val found_closing_brace = false;\n\n                while idx < len {\n                    val c = chars[idx];\n\n                    if c == \"}\" {\n                        idx += 1;\n                        found_closing_brace = true;\n                        break;\n                    } elsif c == \":\" && !has_style {\n                        has_style = true;\n                        idx += 1;\n                    } elsif !has_style {\n                        num_str += c;\n                        idx += 1;\n                    } else {\n                        style_str += c;\n                        idx += 1;\n                    }\n                }\n\n                if !found_closing_brace {\n                    if has_style {\n                        ret += \"{\" + num_str + \":\" + style_str;\n                    } else {\n                        ret += \"{\" + num_str;\n                    }\n                    continue;\n                }\n\n                match Int.parse(num_str) {\n                    case Ok(i) => {\n                        if i >= varargs.len() {\n                            if has_style {\n                                ret += \"{\" + num_str + \":\" + style_str + \"}\";\n                            } else {\n                                ret += \"{\" + num_str + \"}\";\n                            }\n                        } else {\n                            val arg = varargs[i];\n                            if hasattr(arg, \"prettyprint\") {\n                                val pp_arity = arity(arg.prettyprint);\n                                val accepts_1 = pp_arity.can_call_with_argc(1);\n                                val accepts_0 = pp_arity.can_call_with_argc(0);\n                                # Decision logic for calling prettyprint:\n                                # - If prettyprint(x) is a valid signature and no style string is provided,\n                                #   we would prefer to call prettyprint() with no arguments.\n                                # - However, if calling with no arguments would fail, use the 1-argument version\n                                #   with an empty style string if that's the only allowed call.\n                                if (has_style && accepts_1) || (!has_style && accepts_1 && !accepts_0) {\n                                    ret += arg.prettyprint(style_str);\n                                } elsif accepts_0 {\n                                    ret += arg.prettyprint();\n                                } else {\n                                    ret += prettyprint(arg);\n                                }\n                            } else {\n                                ret += prettyprint(arg);\n                            }\n                        }\n                    }\n                } else {\n                    if has_style {\n                        ret += \"{\" + num_str + \":\" + style_str + \"}\";\n                    } else {\n                        ret += \"{\" + num_str + \"}\";\n                    }\n                }\n\n                continue;\n            }\n\n            ret += c;\n            idx += 1;\n        }\n\n        return ret;\n    }\n\n    func substring(from: Int, to: Int) {\n        val ret = \"\";\n        while from < this.len() {\n            if from > to {\n                break;\n            }\n            ret = ret + this[from];\n            from += 1;\n        }\n\n        return ret;\n    }\n\n    func hash() {\n        val ret = 0;\n        for b in this.bytes() {\n            ret = 31 * ret + b;\n        }\n\n        return ret;\n    }\n\n    func join(iter) {\n        val ret = \"\";\n        val first = true;\n        for item in iter {\n            val item = prettyprint(item);\n            if !first {\n                ret += this;\n            }\n            ret += item;\n            first = false;\n        }\n        return ret;\n    }\n\n    func remove(pattern) = this.replace(pattern, \"\");\n}\n\nextension String {\n    func printf(...) {\n        val s = this._format_impl(varargs);\n        print(s);\n    }\n}\n"
  },
  {
    "path": "lib/aria/core/unimplemented.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nextension Unimplemented {\n    func prettyprint() = \"unimplemented\";\n\n    operator ==(rhs) = rhs isa Unimplemented;\n}\n"
  },
  {
    "path": "lib/aria/core/unit.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: no_std;\n\nextension Unit {\n    type func new() = Unit::unit;\n\n    func prettyprint() = \"unit\";\n\n    operator ==(rhs) = rhs isa Unit;\n\n    # this is normally provided by the compiler, but since Unit is a builtin type we need to provide it here\n    func is_unit() = true;\n}\n"
  },
  {
    "path": "lib/aria/date/instant.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\nimport tz_info from aria.date.timezone;\nimport SipHasher from aria.structures.hash.algo.sip;\n\nfunc is_leap_year(year: Int) {\n    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);\n}\n\nfunc leap_years_since_1970(year: Int) {\n    return ((year - 1969) / 4) - ((year - 1901) / 100) + ((year - 1601) / 400);\n}\n\nfunc leap_years_through_end_of(year: Int) {\n    return (year / 4) - (year / 100) + (year / 400);\n}\n\nval SECONDS_PER_MINUTE = 60;\nval SECONDS_PER_HOUR = 3600;\nval SECONDS_PER_DAY = 86400;\nval DAYS_PER_YEAR = 365;\nval EPOCH_YEAR = 1970;\n\nval CUMULATIVE_DAYS =      [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];\nval LEAP_CUMULATIVE_DAYS = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];\n\nval MONTH_NAMES = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\nfunc offset_to_string(offset_minutes) {\n    match offset_minutes {\n        == 0 => { return \"\"; }\n        < 0 => { offset_minutes = -offset_minutes;  }\n    }\n\n    val hours = offset_minutes / 60;\n    val minutes = offset_minutes % 60;\n    val sign = offset_minutes >= 0 ? \"+\" : \"-\";\n    return \"{0}{1:2}:{2:2}\".format(sign, hours, minutes);\n}\n\nfunc split_ms_floor(timestamp_ms: Int) {\n    val sec = timestamp_ms / 1000;\n    val ms  = timestamp_ms % 1000;\n    if ms < 0 {\n        return [sec - 1, ms + 1000];\n    } else {\n        return [sec, ms];\n    }\n}\n\nstruct Instant {\n    type func _before_epoch(timestamp_ms) {\n        val parts = split_ms_floor(timestamp_ms);\n        val timestamp_s = parts[0];\n        val millisecond = parts[1];\n\n        val days = timestamp_s / SECONDS_PER_DAY;\n        val rem = timestamp_s % SECONDS_PER_DAY;\n\n        while rem < 0 {\n            rem += SECONDS_PER_DAY;\n            days -= 1;\n        }\n\n        while rem >= SECONDS_PER_DAY {\n            rem -= SECONDS_PER_DAY;\n            days += 1;\n        }\n\n        val hour = rem / SECONDS_PER_HOUR;\n        rem %= SECONDS_PER_HOUR;\n        val minute = rem / 60;\n        val second = rem % 60;\n\n        val year = 1970;\n        while true {\n            if days >= 0 {\n                if is_leap_year(year) {\n                    if days < 366 {\n                        break;\n                    }\n                } else {\n                    if days < 365 {\n                        break;\n                    }\n                }\n            }\n\n            val yg = year + days / 365;\n            if days % 365 < 0 {\n                yg -= 1;\n            }\n            days -= ((yg - year) * 365 + leap_years_through_end_of(yg - 1) - leap_years_through_end_of(year - 1));\n            year = yg;\n        }\n\n        val months = is_leap_year(year) ? LEAP_CUMULATIVE_DAYS : CUMULATIVE_DAYS;\n\n        val month = 1;\n        for i in Range.from(1).through(12) {\n            if days < months[i] {\n                month = i;\n                break;\n            }\n        }\n\n        val day = (days - months[month - 1]) + 1;\n\n        return alloc(This) {\n            .year,\n            .month,\n            .day,\n            .hour,\n            .minute,\n            .second,\n            .millisecond,\n        };\n    }\n\n    type func _after_epoch(timestamp_ms) {\n        val total_seconds = timestamp_ms / 1000;\n        \n        val year = EPOCH_YEAR + (total_seconds / (DAYS_PER_YEAR * SECONDS_PER_DAY));\n\n        while true {\n            val days_since_epoch = (year - EPOCH_YEAR) * 365 + leap_years_since_1970(year);\n            val seconds_since_epoch = days_since_epoch * SECONDS_PER_DAY;\n            \n            if total_seconds >= seconds_since_epoch {\n                break;\n            }\n            year -= 1;\n        }\n\n        val day_of_year = (total_seconds / SECONDS_PER_DAY) - ((year - EPOCH_YEAR) * 365 + leap_years_since_1970(year));\n        \n        val months = CUMULATIVE_DAYS;\n        if is_leap_year(year) {\n            months = LEAP_CUMULATIVE_DAYS;\n        }\n\n        val month = 12;\n        for i in Range.from(1).through(11) {\n            if day_of_year < months[i] {\n                month = i;\n                break;\n            }\n        }\n\n        val day = (day_of_year - months[month - 1]) + 1;\n\n        val remaining_seconds = total_seconds % SECONDS_PER_DAY;\n        val hour = remaining_seconds / SECONDS_PER_HOUR;\n        remaining_seconds %= SECONDS_PER_HOUR;\n\n        val minute = remaining_seconds / SECONDS_PER_MINUTE;\n        val second = remaining_seconds % SECONDS_PER_MINUTE;\n\n        return alloc(This) {\n            .year = year,\n            .month = month,\n            .day = day,\n            .hour = hour,\n            .minute = minute,\n            .second = second,\n            .millisecond = timestamp_ms % 1000,\n        };\n    }\n\n    type func new_with_utc_timestamp(timestamp_ms) {\n        return This.new_with_timestamp_and_offset(timestamp_ms, 0);\n    }\n\n    type func new_with_timestamp_and_offset(timestamp_ms, offset_minutes) {\n        val offset_ms = offset_minutes * SECONDS_PER_MINUTE * 1000;\n        val actual_timestamp_ms = timestamp_ms + offset_ms;\n        val i = (actual_timestamp_ms >= 0 ? Instant._after_epoch(actual_timestamp_ms) : Instant._before_epoch(actual_timestamp_ms)){\n            .utc_timestamp_ms = timestamp_ms,\n            .offset_minutes,\n        };\n        return i;\n    }\n\n    type func new_with_local_timestamp(timestamp_ms) {\n        val tz_offset = tz_info()[0];\n        val offset_ms = tz_offset * SECONDS_PER_MINUTE * 1000;\n\n        return Instant.new_with_timestamp_and_offset(timestamp_ms, tz_offset);\n    }\n\n    type func now() {\n        val tz_offset = tz_info()[0];\n\n        return Instant.new_with_timestamp_and_offset(now(), tz_offset);\n    }\n\n    instance func with_timezone_offset(offset_minutes) {\n        return Instant.new_with_timestamp_and_offset(this.utc_timestamp_ms, offset_minutes);\n    }\n\n    instance func prettyprint() {\n        return \"{0} {1} {2} {3:2}:{4:2}:{5:2}.{6:3}{7}\".format(\n            MONTH_NAMES[this.month - 1],\n            this.day,\n            this.year,\n            this.hour,\n            this.minute,\n            this.second,\n            this.millisecond,\n            offset_to_string(this.offset_minutes)\n        );\n    }\n\n    func hash() {\n        val hasher = SipHasher.new(0x0706050403020100, 0x0f0e0d0c0b0a0908);\n        hasher.write(this.utc_timestamp_ms);\n        hasher.write(this.offset_minutes);\n        return hasher.finish();\n    }\n\n    operator == (other: Instant) {\n        return this.utc_timestamp_ms == other.utc_timestamp_ms && this.offset_minutes == other.offset_minutes;\n    }\n}\n"
  },
  {
    "path": "lib/aria/date/timezone.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_timezone\");\n"
  },
  {
    "path": "lib/aria/io/file.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_file\");\n\nimport guard from aria.utils.guard;\nimport aria.io.path;\n\nstruct File {\n    struct IOError {\n        type func new(message: String) {\n            return alloc(This) {\n                .message = message\n            };\n        }\n\n        instance func prettyprint() {\n            return \"IO error: {0}\".format(this.message);\n        }\n    }\n\n    func guard_exit() {\n        this.close();\n    }\n\n    func close() {\n        this._close();\n    }\n\n    # the values here must be kept in sync with native-libs/file\n    struct OpenMode {\n        type func new() {\n            return alloc(This) {\n                .mode = 0,\n            };\n        }\n\n        func read() {\n            this.mode = this.mode | 1;\n            return this;\n        }\n\n        func write() {\n            this.mode = this.mode | 2;\n            return this;\n        }\n\n        func append() {\n            this.mode = this.mode | 4;\n            return this;\n        }\n\n        func truncate() {\n            this.mode = this.mode | 8;\n            return this;\n        }\n\n        func create() {\n            this.mode = this.mode | 16;\n            return this;\n        }\n    }\n\n    type func open(path, mode: File.OpenMode) {\n        if path isa aria.io.path.Path {\n            path = path.prettyprint();\n        }\n\n        return File._new(path, mode.mode);\n    }\n\n    func read_all() {\n        return this._read_all();\n    }\n\n    func read(n: Int) {\n        val buffer = this._read_count(n);\n        return String.new_with_bytes(buffer);\n    }\n\n    func write(s) {\n        this._write_str(s);\n    }\n\n    func try_readln() {\n        val buffer = [];\n        val c = 0;\n        try {\n            c = this._read_count(1);\n        } catch e {\n            return Maybe::None;\n        }\n        if c[0] == 10 {\n            return Maybe::Some(\"\");\n        }\n        while true {\n            buffer.append(c[0]);\n            try {\n                c = this._read_count(1);\n            } catch e {\n                break;\n            }\n            if c[0] == 10 {\n                break;\n            }\n        }\n        return Maybe::Some(String.new_with_bytes(buffer));\n    }\n\n    # this is slow!\n    func readln() {\n        val maybe_line = this.try_readln();\n        return maybe_line ?? \"\";\n    }\n\n    func writeln(s) {\n        this.write(s);\n        this.write(\"\\n\");\n    }\n\n    func get_position() {\n        return this._getpos();\n    }\n\n    func set_position(offset: Int) {\n        this._setpos(offset);\n    }\n\n    func len() {\n        return this._getsize();\n    }\n\n    enum SeekMode {\n        case Start(Int),\n        case Current(Int),\n        case End(Int),\n    }\n\n    func seek(mode: File.SeekMode) {\n        match mode {\n            case Start(offset) => {\n                return this.set_position(offset);\n            },\n            case Current(offset) => {\n                return this.set_position(this.get_position() + offset);\n            },\n            case End(offset) => {\n                return this.set_position(this.len() + offset);\n            },\n        }\n    }\n\n    func flush() {\n        this._flush();\n    }\n\n    func lines() {\n        return FileLineIterator.new(this);\n    }\n}\n\nstruct FileLineIterator {\n    type func new(file) {\n        return alloc(This) {\n            .file = file,\n        };\n    }\n\n    func iterator() {\n        return this;\n    }\n\n    func next() {\n        return this.file.try_readln();\n    }\n}\n\nextension aria.io.path.Path {\n    func read() {\n        return guard(File.open(this.prettyprint(), File.OpenMode.new().read())).do(|file| => {\n            return file.read_all();\n        });\n    }\n\n    func write(text) {\n        guard(File.open(this.prettyprint(), File.OpenMode.new().write().truncate())).do(|file| => {\n            file.write(text);\n        });\n    }\n}\n"
  },
  {
    "path": "lib/aria/io/path.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_path\");\nimport aria.date.instant;\nimport Iterator from aria.iterator.mixin;\n\nstruct Path {\n    struct Error {\n        type func new(msg) = alloc(This) {.msg};\n\n        func prettyprint() {\n            return \"path error: {0}\".format(this.msg);\n        }\n    }\n    \n    struct Iterator {\n        func iterator() { return this; }\n\n        include Iterator\n    }\n\n    type func new_with_current_directory() {\n        return This._cwd();\n    }\n\n    type func new_with_environment_variable(var) {\n        return getenv(var).apply(|p| => {\n            return This.new(p);\n        });\n    }\n\n    type func new(s: String) {\n        return This._new(s);\n    }\n\n    type func glob(pattern: String) {\n        return This._glob(pattern);\n    }\n\n    func append(rhs: String|Path) {\n        if rhs isa String {\n            this._append(rhs);\n        } elsif rhs isa Path {\n            this._append(rhs.prettyprint());\n        }\n\n        return this;\n    }\n\n    operator /(rhs: String|Path) {\n        return Path.new(this.prettyprint()).append(rhs);\n    }\n\n    func parent() {\n        return Path.new(this.prettyprint()).pop();\n    }\n\n    func created() {\n        match this._when_created() {\n            case Ok(val) => {\n                return Result::Ok(aria.date.instant.Instant.new_with_local_timestamp(val));\n            }\n            case Err(err) => {\n                return Result::Err(err);\n            }\n        };\n    }\n\n    func accessed() {\n        match this._when_accessed() {\n            case Ok(val) => {\n                return Result::Ok(aria.date.instant.Instant.new_with_local_timestamp(val));\n            }\n            case Err(err) => {\n                return Result::Err(err);\n            }\n        };\n    }\n\n    func modified() {\n        match this._when_modified() {\n            case Ok(val) => {\n                return Result::Ok(aria.date.instant.Instant.new_with_local_timestamp(val));\n            }\n            case Err(err) => {\n                return Result::Err(err);\n            }\n        };\n    }\n\n    # we could use the builtin _copy, except for type validation\n    func copy_to(other: Path) {\n        this._copy(other);\n    }\n\n    func hash() {\n        return this.prettyprint().hash();\n    }\n}\n"
  },
  {
    "path": "lib/aria/iterator/enumerate.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Enumerate {\n    type func new(iter) {\n        if hasattr(iter, \"iterator\") {\n            iter = iter.iterator();\n        }\n        return alloc(This) {\n            .iter = iter,\n            .index = 0,\n        };\n    }\n\n    func iterator() {\n        return this;\n    }\n\n    func next() {\n        val iter_next = this.iter.next();\n        match iter_next {\n            case None => {\n                return Maybe::None;\n            },\n            case Some(v) => {\n                val next = Maybe::Some(Box(){\n                    .index = this.index,\n                    .value = v,\n                });\n                this.index += 1;\n                return next;\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/iterator/mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok, err from aria.core.result;\n\nstruct FilteringIterator {\n    type func new(i, f) {\n        return alloc(This){\n            .it = i,\n            .clause = f,\n        };\n    }\n\n    func next() {\n        while true {\n            val nv = this.it.next();\n            match nv {\n                case Some(x) => {\n                    if this.clause(x) {\n                        return Maybe::Some(x);\n                    } else {\n                        continue;\n                    }\n                },\n                case None => {\n                    return Maybe::None;\n                }\n            }\n        }\n    }\n}\n\nstruct MappingIterator {\n    type func new(i, f) {\n        return alloc(This){\n            .it = i,\n            .clause = f,\n        };\n    }\n\n    func next() {\n        while true {\n            val nv = this.it.next();\n            match nv {\n                case None => {\n                    return Maybe::None;\n                },\n                case Some(x) => {\n                    return Maybe::Some(this.clause(x));\n                }\n            }\n        }\n    }\n}\n\nstruct CountReducer {\n    type func new() = alloc(This) {.count = 0};\n    operator () (_x,_y) {\n        this.count += 1;\n        return this;\n    }\n}\n\nstruct TruncatedIterator {\n    type func new(i, n: Int) {\n        return alloc(This){\n            .it = i,\n            .remaining = n,\n        };\n    }\n\n    func next() {\n        if this.remaining <= 0 {\n            return Maybe::None;\n        }\n        this.remaining -= 1;\n        return this.it.next();\n    }\n}\n\nfunc append_to_list(x,y) {\n    x.append(y);\n    return x;\n}\n\nmixin Iterator {\n    # allow running a for loop directly on an iterator\n    func iterator() = this;\n\n    func where(f) {\n        return FilteringIterator.new(this,f);\n    }\n\n    func map(f) {\n        return MappingIterator.new(this,f);\n    }\n\n    func to_list() {\n        return this.reduce(append_to_list, []);\n    }\n\n    func flatten_results() {\n        val out = [];\n        for v in this {\n            match v {\n                isa Result and case Ok(x) => { out.append(x); },\n                isa Result and case Err(e) => { return err(e); },\n            } else {\n                out.append(v);\n            }\n        }\n    \n        return ok(out);\n    }\n\n    func all(f) {\n        for v in this {\n            if !f(v) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    func any(f) = this.find(f).is_Some();\n\n    func find(f) {\n        for v in this {\n            if f(v) {\n                return Maybe::Some(v);\n            }\n        }\n        return Maybe::None;\n    }\n\n    func position(f) {\n        val index = 0;\n        for v in this {\n            if f(v) {\n                return Maybe::Some(index);\n            }\n            index += 1;\n        }\n        return Maybe::None;\n    }\n\n    func reduce(f, v0) {\n        val acc = v0;\n        for v in this {\n            acc = f(acc, v);\n        }\n        return acc;\n    }\n\n    func sum(v0=0) = this.reduce(|x,y| => x+y, v0);\n\n    func product(v0=1) = this.reduce(|x,y| => x*y, v0);\n\n    func max() {\n        val current_max = this.next()?;\n        for v in this {\n            if v > current_max {\n                current_max = v;\n            }\n        }\n        return Maybe::Some(current_max);\n    }\n\n    func min() {\n        val current_min = this.next()?;\n        for v in this {\n            if v < current_min {\n                current_min = v;\n            }\n        }\n        return Maybe::Some(current_min);\n    }\n\n    func count() = this.reduce(|acc,_| => acc + 1, 0);\n\n    func first() = this.next();\n\n    func last() {\n        val last_value = Maybe::None;\n        for v in this {\n            last_value = Maybe::Some(v);\n        }\n        return last_value;\n    }\n\n    func nth(n: Int) {\n        if n < 0 {\n            return Maybe::None;\n        }\n        val current_index = 0;\n        for v in this {\n            if current_index == n {\n                return Maybe::Some(v);\n            }\n            current_index += 1;\n        }\n        return Maybe::None;\n    }\n\n    func skip(n: Int) {\n        while n > 0 {\n            if this.next().is_None() { break; };\n            n -= 1;\n        }\n        return this;\n    }\n\n    func truncate(n: Int) = TruncatedIterator.new(this, n);\n}\n\nextension FilteringIterator {\n    include Iterator\n}\n\nextension MappingIterator {\n    include Iterator\n}\n\nextension TruncatedIterator {\n    include Iterator\n}\n\nextension List.ListIterator {\n    include Iterator\n}\n\nmixin Iterable {\n    func where(f) = this.iterator().where(f);\n    func map(f) = this.iterator().map(f);\n    func reduce(f,v0) = this.iterator().reduce(f,v0);\n    func to_list() = this.iterator().to_list();\n    func all(f) = this.iterator().all(f);\n    func any(f) = this.iterator().any(f);\n    func find(f) = this.iterator().find(f);\n    func position(f) = this.iterator().position(f);\n    func sum(v0=0) = this.iterator().sum(v0);\n    func product(v0=1) = this.iterator().product(v0);\n    func max() = this.iterator().max();\n    func min() = this.iterator().min();\n    func count() = this.iterator().count();\n    func first() = this.iterator().first();\n    func last() = this.iterator().last();\n    func nth(n) = this.iterator().nth(n);\n    func skip(n: Int) = this.iterator().skip(n);\n    func truncate(n: Int) = this.iterator().truncate(n);\n}\n\nextension List {\n    include Iterable\n}\n"
  },
  {
    "path": "lib/aria/iterator/zip.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nfunc iter_or_self(i) {\n    return hasattr(i, \"iterator\") ? i.iterator() : i;\n}\n\nstruct Zip {\n    type func new(...) {\n        val iterators = varargs.iterator().map(iter_or_self).to_list();\n        return alloc(This){\n            .iterators = iterators,\n        };\n    }\n\n    func iterator() {\n        return this;\n    }\n\n    func next() {\n        val next_values = [];\n        for iter in this.iterators {\n            next_values.append(iter.next()?);\n        }\n        return Maybe::Some(next_values);\n    }\n}\n"
  },
  {
    "path": "lib/aria/json/parser.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Map from aria.structures.map;\nimport aria.string.classes;\nimport JsonValue from aria.json.value;\nimport JsonNull from aria.json.value;\nimport ok, err from aria.core.result;\n\nstruct JsonStream {\n    type func new(s) {\n        return alloc(This) { .input = s.chars(), .pos = 0 };\n    }\n\n    func peek() {\n        return this.pos < this.input.len() ? this.input[this.pos] : Maybe::None;\n    }\n\n    func next() {\n        val c = this.peek();\n        this.pos += 1;\n        return c;\n    }\n\n    func eat(expected) {\n        if this.peek() == expected {\n            this.next();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    func skip_whitespace() {\n        while true {\n            val c = this.peek();\n            if c == ' ' || c == '\\t' || c == '\\n' || c == '\\r' {\n                this.next();\n            } else {\n                break;\n            }\n        }\n    }\n}\n\nextension JsonValue {\n    type func parse(s) {\n        return ok(parse_value(JsonStream.new(s))?);\n    }\n}\n\nstruct JsonParseError {\n    type func new(why: String) {\n        return alloc(This) {\n            .message = why,\n        };\n    }\n\n    func prettyprint() {\n        return \"JsonParseError: \" + this.message;\n    }\n}\n\nfunc json_err(msg) {\n    return err(JsonParseError.new(msg));\n}\n\nfunc parse_value(stream) {\n    stream.skip_whitespace();\n    val c = stream.peek();\n\n    if c == '\"' {\n        return JsonValue::String(parse_string(stream)?);\n    } elsif c == '{' {\n        return JsonValue::Object(parse_object(stream)?);\n    } elsif c == '[' {\n        return JsonValue::Array(parse_array(stream)?);\n    } elsif c == 't' {\n        return parse_true(stream)?;\n    } elsif c == 'f' {\n        return parse_false(stream)?;\n    } elsif c == 'n' {\n        return parse_null(stream)?;\n    } elsif c.is_digit() || c == '-' {\n        return JsonValue::Number(parse_number(stream))?;\n    } else {\n        return json_err(\"Not a valid JSON value: \" + c);\n    }\n}\n\nfunc parse_string(stream) {\n    if !stream.eat('\"') {\n        return json_err(\"missing quotes in JSON string\");\n    }\n\n    val result = \"\";\n    while true {\n        val c = stream.next();\n        if c == '\"' {\n            break;\n        } elsif c == '\\\\' {\n            val esc = stream.next();\n            if esc == 'n' {\n                result += '\\n';\n            } elsif esc == 't' {\n                result += '\\t';\n            } elsif esc == '\"' {\n                result += '\"';\n            } elsif esc == '\\\\' {\n                result += '\\\\';\n            } else {\n                return json_err(\"invalid escape sequence in JSON string\");\n            }\n        } else {\n            result += c;\n        }\n    }\n\n    return ok(result);\n}\n\nfunc parse_number(stream) {\n    val text = \"\";\n    if stream.peek() == '-' {\n        text += stream.next();\n    }\n\n    while true {\n        val c = stream.peek();\n        if c.is_digit() {\n            text += stream.next();\n        } else {\n            break;\n        }\n    }\n\n    if stream.peek() == '.' {\n        text += stream.next();\n        while true {\n            val c = stream.peek();\n            if c.is_digit() {\n                text += stream.next();\n            } else {\n                break;\n            }\n        }\n    }\n\n    return Float.parse(text)?;\n}\n\nfunc parse_true(stream) {\n    if stream.next() != 't' || stream.next() != 'r' || stream.next() != 'u' || stream.next() != 'e' {\n        return json_err(\"invalid boolean true value in JSON\");\n    } else {\n        return ok(JsonValue::Boolean(true));\n    }\n}\n\nfunc parse_false(stream) {\n    if stream.next() != 'f' || stream.next() != 'a' || stream.next() != 'l' || stream.next() != 's' || stream.next() != 'e' {\n        return json_err(\"invalid boolean false value in JSON\");\n    } else {\n        return ok(JsonValue::Boolean(false));\n    }\n}\n\nfunc parse_null(stream) {\n    if stream.next() != 'n' || stream.next() != 'u' || stream.next() != 'l' || stream.next() != 'l' {\n        return json_err(\"invalid null value in JSON\");\n    } else {\n        return ok(JsonValue::Null(alloc(JsonNull)));\n    }\n}\n\nfunc parse_object(stream) {\n    val map = Map.new();\n    stream.eat('{');\n    stream.skip_whitespace();\n\n    if stream.peek() == '}' {\n        stream.next();\n        return map;\n    }\n\n    while true {\n        stream.skip_whitespace();\n        val key = parse_string(stream)?;\n        stream.skip_whitespace();\n        if !stream.eat(':') {\n            return json_err(\"Invalid JSON object key-value pair\");\n        }\n\n        val value = parse_value(stream)?;\n        map.set(key, value);\n        stream.skip_whitespace();\n\n        if stream.eat('}') {\n            break;\n        } elsif stream.eat(',') {\n            continue;\n        } else {\n            return json_err(\"Unexpected character in JSON object\");\n        }\n    }\n\n    return ok(map);\n}\n\nfunc parse_array(stream) {\n    val list = [];\n    stream.eat('[');\n    stream.skip_whitespace();\n\n    if stream.peek() == ']' {\n        stream.next();\n        return list;\n    }\n\n    while true {\n        val value = parse_value(stream)?;\n        list.append(value);\n        stream.skip_whitespace();\n\n        if stream.eat(']') {\n            break;\n        } elsif stream.eat(',') {\n            continue;\n        } else {\n            return json_err(\"Unexpected character in JSON array\");\n        }\n    }\n\n    return ok(list);\n}\n"
  },
  {
    "path": "lib/aria/json/value.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.structures.map;\n\nstruct JsonNull {}\n\nenum JsonValue {\n    case Object(aria.structures.map.Map),\n    case Array(List),\n    case String(String),\n    case Number(Float),\n    case Boolean(Bool),\n    case Null(JsonNull),\n}\n\nextension JsonValue {\n    func flatten() {\n        match this {\n            case Boolean(x) => {\n                return x;\n            },\n            case Number(x) => {\n                return x;\n            },\n            case String(x) => {\n                return x;\n            },\n            case Array(x) => {\n                val ret = [];\n                for v in x {\n                    ret.append(v.flatten());\n                }\n                return ret;\n            },\n            case Object(x) => {\n                val ret = aria.structures.map.Map.new();\n                for v in x {\n                    ret.set(v.key, v.value.flatten());\n                }\n                return ret;\n            },\n            case Null(x) => {\n                return x;\n            },\n        }\n    }\n\n    func prettyprint() {\n        match this {\n            case Boolean(x) => {\n                return \"{0}\".format(x);\n            },\n            case Number(x) => {\n                return \"{0}\".format(x);\n            },\n            case String(x) => {\n                return '\"{0}\"'.format(x);\n            },\n            case Array(x) => {\n                val items = [];\n                for v in x {\n                    items.append(v.prettyprint());\n                }\n                return \"[{0}]\".format(items.join(\", \"));\n            },\n            case Object(x) => {\n                val items = [];\n                for v in x {\n                    items.append('\"{0}\": {1}'.format(v.key, v.value));\n                }\n                return \"{\" + \"{0}\".format(items.join(\", \")) + \"}\" + \"}\";\n            },\n            case Null(x) => {\n                return \"null\";\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/json/writer.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Map from aria.structures.map;\nimport JsonValue from aria.json.value;\nimport JsonNull from aria.json.value;\nimport ok, err from aria.core.result;\n\n# this is a type-check only prototype\nfunc _to_json_thing(this) {}\n\nstruct JsonConvertError {\n    type func new(why: String) {\n        return alloc(This) {\n            .message = why,\n        };\n    }\n\n    func prettyprint() {\n        return \"JsonConvertError: \" + this.message;\n    }\n}\n\nfunc json_err(msg) {\n    return err(JsonConvertError.new(msg));\n}\n\nextension JsonValue {\n    type func new_with_value(x) {\n        match x {\n            isa String => {\n                return ok(JsonValue::String(x));\n            },\n            isa Int => {\n                return ok(JsonValue::Number(x + 0.0f));\n            },\n            isa Float => {\n                return ok(JsonValue::Number(x));\n            },\n            isa Bool => {\n                return ok(JsonValue::Boolean(x));\n            },\n            isa List => {\n                val ret = [];\n                for item in x {\n                    ret.append(JsonValue.new_with_value(item)?);\n                }\n                return ok(JsonValue::Array(ret));\n            }\n            isa Map => {\n                val ret = Map.new();\n                for item in x {\n                    val key = item.key;\n                    if !(key isa String) {\n                        key = format(\"{0}\", key);\n                    }\n                    val value = JsonValue.new_with_value(item.value)?;\n                    ret.set(key, value);\n                }\n                return ok(JsonValue::Object(ret));\n            }\n            isa JsonNull => {\n                return ok(JsonValue::Null(alloc(JsonNull)));\n            }\n        } else {\n            if hasattr(x, \"to_json_value\") {\n                val to_json_value = x.to_json_value;\n                if arity(to_json_value).can_call_with_argc(0) {\n                    return to_json_value()?;\n                }\n            }\n        }\n\n        return json_err(\"type of value {0} cannot be converted as JSON\".format(x));\n    }\n}\n\nfunc escape_json_string(s: String) {\n    val result = \"\";\n    for c in s.chars() {\n        if c == '\"' {\n            result += '\\\\\"';\n        } elsif c == '\\\\' {\n            result += \"\\\\\\\\\";\n        } elsif c == '\\n' {\n            result += \"\\\\n\";\n        } elsif c == '\\r' {\n            result += \"\\\\r\";\n        } elsif c == '\\t' {\n            result += \"\\\\t\";\n        } elsif c == '\\b' {\n            result += \"\\\\b\";\n        } elsif c == '\\f' {\n            result += \"\\\\f\";\n        } else {\n            result += c;\n        }\n    }\n    return result;\n}\n\nextension JsonValue {\n    func to_json_string() {\n        match this {\n            case Object(map) => {\n                val parts = [];\n                for entry in map {\n                    val key = escape_json_string(entry.key);\n                    val value_str = entry.value.to_json_string();\n                    parts.append('\"' + key + '\":' + value_str);\n                }\n                return \"{\" + parts.join() + \"}\";\n            },\n\n            case Array(items) => {\n                val parts = [];\n                for item in items {\n                    parts.append(item.to_json_string());\n                }\n                return \"[\" + parts.join() + \"]\";\n            },\n\n            case String(s) => {\n                return '\"' + escape_json_string(s) + '\"';\n            },\n\n            case Number(n) => {\n                return \"{0}\".format(n);\n            },\n\n            case Boolean(b) => {\n                return b ? \"true\" : \"false\";\n            },\n\n            case Null(x) => {\n                return \"null\";\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/network/request.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_http\");\n\nimport Map from aria.structures.map;\nimport JsonValue, JsonNull from aria.json.value;\nimport aria.json.writer;\n\nstruct Request {\n    struct Response {\n        func prettyprint() {\n            return \"aria.network.Request.Response(code={0})\".format(this.status_code);\n        }\n    }\n\n    struct Error {\n        type func new(msg) {\n            return alloc(This) {\n                .msg = msg,\n            };\n        }\n\n        func prettyprint() {\n            return \"network error: {0}\".format(this.msg);\n        }\n    }\n\n    type func new(url: String) {\n        return alloc(This) {\n            .url = url,\n            .headers = Map.new(),\n            .timeout = 30.0f,\n        };\n    }\n\n    func get() {\n        # the native impl takes and returns headers as a key/value pair list\n        # but we use Map in Aria - this code handles that conversion logic\n\n        val headers = [];\n        for h in this.headers {\n            headers.append([h.key, h.value]);\n        }\n\n        val response = this._get(headers)?;\n\n        val headers = Map.new();\n        for header in response.headers {\n            headers.set(header[0], header[1]);\n        }\n        response.headers = headers;\n\n        return Result::Ok(response);\n    }\n\n    func post(data: String) {\n        # the native impl takes and returns headers as a key/value pair list\n        # but we use Map in Aria - this code handles that conversion logic\n\n        val headers = [];\n        for h in this.headers {\n            headers.append([h.key, h.value]);\n        }\n\n        val response = this._post(headers, data)?;\n\n        val headers = Map.new();\n        for header in response.headers {\n            headers.set(header[0], header[1]);\n        }\n        response.headers = headers;\n\n        return Result::Ok(response);\n    }\n\n    func post_as_json(data) {\n        val the_val = JsonValue.new_with_value(data)?.to_json_string();\n        this.headers[\"Content-Type\"] = \"application/json\";\n        return this.post(the_val);\n    }\n}\n"
  },
  {
    "path": "lib/aria/network/retry.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum RetryResult {\n    case Pass(Any),\n    case Fail(Maybe), # last value if any\n    case Exception(Any), # last exception from f/check\n}\n\nextension RetryResult {\n    func _op_try_view() {\n        match this {\n            case Pass(v) => {\n                return Result::Ok(v);\n            },\n            case Fail(v) => {\n                return Result::Err(v);\n            },\n            case Exception(e) => {\n                # swallow the difference between a failure and an exception\n                return Result::Err(e);\n            }\n        }\n    }\n}\n\nfunc retry(f, check, attempts_count = 3, delay_ms = 500) {\n    if attempts_count <= 0 {\n        return RetryResult::Fail(Maybe::None);\n    }\n    if delay_ms < 0 {\n        return RetryResult::Fail(Maybe::None);\n    }\n\n    val last_result = Maybe::None;\n    val last_exception = Maybe::None;\n\n    while attempts_count > 0 {\n        last_exception = Maybe::None;\n\n        # same as a do { } while(false) in C, since there is no path but out\n        while true {\n            val result = Maybe::None;\n            try {\n                result = f();\n            } catch e {\n                last_exception = Maybe::Some(e);\n                break;\n            }\n\n            val checked = false;\n            try {\n                checked = check(result);\n            } catch e {\n                last_exception = Maybe::Some(e);\n                break;\n            }\n\n            if checked {\n                return RetryResult::Pass(result);\n            } else {\n                last_result = Maybe::Some(result);\n            }\n\n            break;\n        }\n\n        attempts_count -= 1;\n\n        if attempts_count > 0 {\n            sleep_ms(delay_ms);\n        }\n    }\n\n    if last_exception.is_Some() {\n        return RetryResult::Exception(last_exception.unwrap_Some());\n    } else {\n        return RetryResult::Fail(last_result);\n    }\n}\n"
  },
  {
    "path": "lib/aria/numerics/complex.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Complex {\n    type func new(r: Int|Float, i: Int|Float = 0) {\n        return alloc(This) {\n            .real = r + 0.0f, # ensure floating point\n            .imag = i + 0.0f, # ensure floating point\n        };\n    }\n\n    type func zero() {\n        return This.new(0,0);\n    }\n\n    func conj() {\n        return Complex.new(this.real, -this.imag);\n    }\n\n    func reciprocal() {\n        val den = (this.real * this.real + this.imag * this.imag) + 0.0f;\n        return Complex.new(this.real/den, -this.imag/den);\n    }\n\n    func prettyprint() {\n        if this.imag == 0 {\n            return \"{0}\".format(this.real);\n        } elsif this.real == 0 {\n            return \"{0}i\".format(this.imag);\n        } elsif this.imag >= 0 {\n            return \"{0}+{1}i\".format(this.real, this.imag);\n        } else {\n            return \"{0}{1}i\".format(this.real, this.imag);\n        }\n    }\n\n    operator +(rhs) {\n        if (rhs isa Int) || (rhs isa Float) {\n            return Complex.new(this.real + rhs, this.imag);\n        } elsif rhs isa Complex {\n            return Complex.new(this.real + rhs.real, this.imag + rhs.imag);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator +(lhs) {\n        return this._op_impl_add(lhs);\n    }\n\n    operator *(rhs) {\n        if (rhs isa Int) || (rhs isa Float) {\n            return Complex.new(this.real * rhs, this.imag * rhs);\n        } elsif rhs isa Complex {\n            val real_part = this.real * rhs.real - this.imag * rhs.imag;\n            val imag_part = this.real * rhs.imag + this.imag * rhs.real;\n            return Complex.new(real_part, imag_part);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator *(lhs) {\n        return this._op_impl_mul(lhs);\n    }\n\n    reverse operator /(lhs) {\n        if (lhs isa Int) || (lhs isa Float) {\n            lhs = Complex.new(lhs,0);\n        }\n\n        if lhs isa Complex {\n            return lhs / this;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator /(rhs) {\n        if (rhs isa Int) || (rhs isa Float) {\n            return Complex.new(this.real / rhs, this.imag / rhs);\n        } elsif rhs isa Complex {\n            return this * rhs.reciprocal();\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator -(lhs) {\n        if (lhs isa Int) || (lhs isa Float) {\n            return Complex.new(lhs - this.real, -this.imag);\n        } elsif lhs isa Complex {\n            return Complex.new(lhs.real - this.real, lhs.imag - this.imag);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator -(rhs) {\n        if (rhs isa Int) || (rhs isa Float) {\n            return Complex.new(this.real - rhs, this.imag);\n        } elsif rhs isa Complex {\n            return Complex.new(this.real - rhs.real, this.imag - rhs.imag);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n\n    operator ==(rhs) {\n        if rhs isa Complex {\n            return this.real == rhs.real && this.imag == rhs.imag;\n        } elsif (rhs isa Int) || (rhs isa Float) {\n            return this.real == rhs && this.imag == 0;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    func hash() {\n        val h = this.real.hash() ^ (this.imag.hash() + 0x9e3779b97f4a7c15);\n        h = h ^ (h >> 30);\n        h = h * 0xbf58476d1ce4e5b9;\n        h = h ^ (h >> 27);\n        h = h * 0x94d049bb133111eb;\n        h = h ^ (h >> 31);\n        return h;\n    }\n}\n\nextension Complex {\n    type val i = Complex.new(0,1);\n    type val j = Complex.i;\n}\n"
  },
  {
    "path": "lib/aria/numerics/decimal.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport CompareResult, TotalOrdering from aria.ordering.compare;\nimport aria.numerics.int.pow;\n\nfunc pow(x: Int, y: Int) {\n    if y == 0 { return 1; }\n    if y == 1 { return x; }\n    val ret = x;\n    while y > 1 {\n        ret *= x;\n        y -= 1;\n    }\n    return ret;\n}\n\nfunc max(x,y) {\n    return x > y ? x : y;\n}\n\nstruct Decimal {\n    type func parse(v: String) {\n        val parts = v.split(\".\");\n        match parts.len() {\n            == 1 => {\n                val v = Int.parse(parts[0]);\n                return v.apply(|value| => This.new_with_parts(value, 0));\n            },\n            == 2 => {\n                val integer_part = Int.parse(parts[0])?;\n                val decimal_part = parts[1];\n                val scale = decimal_part.len();\n                val combined_str = parts[0] + decimal_part;\n                val value = Int.parse(combined_str);\n                return value.apply(|v| => This.new_with_parts(v, scale));\n            }\n        } else {\n            return Result::Err(\"invalid decimal string\");\n        }\n    }\n\n    type func new(v: Int|Float) {\n        match v {\n            isa Int => {\n                return This.new_with_parts(v, 0);\n            },\n            isa Float => {\n                # relies on Float.prettyprint doing the right thing\n                # really, there should be a way on Float to extract the\n                # integer and fractional parts directly\n                val s = prettyprint(v);\n                val parts = s.split(\".\");\n                match parts.len() {\n                    == 1 => {\n                        return This.new_with_parts(v.int(), 0);\n                    },\n                    == 2 => {\n                        val decimal_part = parts[1];\n                        val scale = decimal_part.len();\n                        val value = (v * pow(10, scale)).int();\n                        return This.new_with_parts(value, scale);\n                    }\n                }\n            }\n        }\n    }\n\n    type func new_with_parts(v: Int, s: Int) {\n        while s > 0 && v % 10 == 0 {\n            v /= 10;\n            s -= 1;\n        }\n\n        return alloc(This){\n            .value = v,\n            .scale = s,\n        };\n    }\n\n    operator u-() {\n        return alloc(Decimal){\n            .value = -this.value,\n            .scale = this.scale,\n        };\n    }\n\n    reverse operator -(lhs) {\n        return -this + lhs;\n    }\n\n    reverse operator /(lhs) {\n        if lhs isa Int {\n            lhs = Decimal.new(lhs);\n        } elsif lhs isa Float {\n            lhs = Decimal.new(lhs);\n        } elsif !(lhs isa Decimal) {\n            throw alloc(Unimplemented);\n        }\n\n        return lhs / this;\n    }\n\n    operator +(other: Int|Float|Decimal) {\n        if other isa Int {\n            other = Decimal.new(other);\n        } elsif other isa Float {\n            other = Decimal.new(other);\n        }\n\n        if this.scale == other.scale {\n            return Decimal.new_with_parts(this.value + other.value, this.scale);\n        } else {\n            val max_scale = max(this.scale, other.scale);\n            val this_value = this.value * pow(10, (max_scale - this.scale));\n            val other_value = other.value * pow(10, (max_scale - other.scale));\n            return Decimal.new_with_parts(this_value + other_value, max_scale);\n        }\n    }\n\n    reverse operator +(lhs) {\n        return this._op_impl_add(lhs);\n    }\n\n    operator -(other: Int|Float|Decimal) {\n        if other isa Int {\n            other = Decimal.new(other);\n        } elsif other isa Float {\n            other = Decimal.new(other);\n        }\n\n        if this.scale == other.scale {\n            return Decimal.new_with_parts(this.value - other.value, this.scale);\n        } else {\n            val max_scale = max(this.scale, other.scale);\n            val this_value = this.value * pow(10, (max_scale - this.scale));\n            val other_value = other.value * pow(10, (max_scale - other.scale));\n            return Decimal.new_with_parts(this_value - other_value, max_scale);\n        }\n    }\n\n    operator *(other: Int|Float|Decimal) {\n        if other isa Int {\n            other = Decimal.new(other);\n        } elsif other isa Float {\n            other = Decimal.new(other);\n        }\n\n        return Decimal.new_with_parts(this.value * other.value, this.scale + other.scale);\n    }\n\n    reverse operator *(lhs) {\n        return this._op_impl_mul(lhs);\n    }\n\n    operator /(other: Int|Float|Decimal) {\n        if other isa Int {\n            other = Decimal.new(other);\n        } elsif other isa Float {\n            other = Decimal.new(other);\n        }\n\n        return Decimal.new_with_parts(this.value * pow(10, other.scale) / other.value, this.scale);\n    }\n\n    func align(other) {\n        if this.scale == other.scale {\n            return [this, other];\n        }\n\n        val max_scale = max(this.scale, other.scale);\n        val this_value = this.value * pow(10, max_scale - this.scale);\n        val other_value = other.value * pow(10, max_scale - other.scale);\n\n        val a0 = alloc(Decimal){ .value=this_value,  .scale=max_scale };\n        val a1 = alloc(Decimal){ .value=other_value, .scale=max_scale };\n\n        return [a0,a1];\n    }\n\n    func comp(other) {\n        if other isa Int {\n            other = Decimal.new(other);\n        } elsif other isa Float {\n            other = Decimal.new(other);\n        } elsif !(other isa Decimal) {\n            throw alloc(Unimplemented);\n        }\n\n        val a = this.align(other);\n\n        if a[0].value == a[1].value {\n            return CompareResult::eq;\n        } elsif a[0].value > a[1].value {\n            return CompareResult::gt;\n        } else {\n            return CompareResult::lt;\n        }\n    }\n\n    func prettyprint(fmt: String = \"\") {\n        if fmt == \"\" {\n            return this.default_prettyprint();\n        }\n\n        val parts = fmt.split(\".\");\n        if parts.len() != 2 || parts[0] != \"\" {\n            return this.default_prettyprint();\n        }\n\n        val n_maybe = Int.parse(parts[1]);\n        match n_maybe {\n            case Err => { return this.default_prettyprint(); },\n            case Ok(N) => {\n                if N <= 0 {\n                    return this.default_prettyprint();\n                }\n\n                if this.scale <= N {\n                    return this.default_prettyprint();\n                }\n\n                val drop = this.scale - N;\n                val factor = 10.pow(drop);\n                val v = this.value;\n\n                val rounded =\n                    v >= 0 ? (v + factor / 2) / factor\n                        : (v - factor / 2) / factor;\n\n                return Decimal.new_with_parts(rounded, N).default_prettyprint();\n            }\n        }\n    }\n\n    func default_prettyprint() {\n        val abs_value_str = prettyprint(this.value.abs());\n        val sign = \"\";\n        if this.value < 0 { sign = \"-\"; }\n\n        if this.scale == 0 {\n            return sign + abs_value_str;\n        }\n\n        val value_str = abs_value_str;\n        val len = value_str.len();\n\n        if len <= this.scale {\n            return sign + \"0.\" + \"0\" * (this.scale - len) + value_str;\n        }\n\n        val integer_part = value_str.substring(0, len - this.scale - 1);\n        val fractional_part = value_str.substring(len - this.scale, len - 1);\n        \n        return sign + integer_part + \".\" + fractional_part;\n    }\n\n    func hash() {\n        val h = this.value ^ (this.scale + 0x9e3779b97f4a7c15);\n        h = h ^ (h >> 30);\n        h = h * 0xbf58476d1ce4e5b9;\n        h = h ^ (h >> 27);\n        h = h * 0x94d049bb133111eb;\n        h = h ^ (h >> 31);\n        return h;\n    }\n\n    include TotalOrdering\n}\n"
  },
  {
    "path": "lib/aria/numerics/float/exp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Float {\n    func ln() {\n        if this <= 0 {\n            throw Float.DomainError.new(\"logarithm undefined for non-positive values\");\n        }\n\n        val LN2 = 0.6931471805599453;\n        val ε = 1.0e-15;\n        val max_iterations = 10000;\n\n        val x = this;\n        val k = 0;\n        val mant = x;\n\n        while mant >= 2.0f {\n            mant = mant / 2.0f;\n            k = k + 1;\n        }\n\n        while mant < 1.0f {\n            mant = mant * 2.0f;\n            k = k - 1;\n        }\n\n        if mant == 1.0f {\n            return k * LN2;\n        }\n\n        val y = (mant - 1.0f) / (mant + 1.0f);\n        val y2 = y * y;\n\n        val term = y;\n        val sum = 0.0f;\n        val n = 1;\n        val iterations = 0;\n        while iterations < max_iterations {\n            sum = sum + term / n;\n            term = term * y2;\n            n = n + 2;\n            iterations = iterations + 1;\n            if (term.abs() / n) < ε {\n                break;\n            }\n        }\n\n        val ln_val = 2.0f * sum;\n        return ln_val + k * LN2;\n    }\n\n    func exp() {\n        val ε = 0.000000000001f;\n        val max_iterations = 1000;\n\n        if this == 0.0f {\n            return 1.0f;\n        }\n\n        val reduced = this;\n        val scale = 0;\n        while reduced.abs() > 0.5f {\n            reduced = reduced / 2.0f;\n            scale = scale + 1;\n        }\n\n        val result = 1.0f;\n        val term = 1.0f;\n        val iterations = 0;\n        while iterations < max_iterations {\n            iterations = iterations + 1;\n            term = term * reduced / iterations;\n            if term.abs() < ε {\n                break;\n            }\n            result = result + term;\n        }\n\n        val i = 0;\n        while i < scale {\n            result = result * result;\n            i = i + 1;\n        }\n\n        return result;\n    }\n\n    func pow(exponent: Int|Float) {\n        match exponent {\n            == 0 => { return 1.0f; },\n            == 1 => { return this; }\n            isa Int => {\n                exponent += 0.0f;\n            }\n        }\n\n        if this < 0 && exponent % 1 != 0 {\n            throw Float.DomainError.new(\"cannot calculate fractional power of negative integer\");\n        }\n\n        val is_exponent_negative = exponent < 0;\n        val abs_exponent = exponent.abs();\n\n        val integer_part = abs_exponent.floor();\n        val fractional_part = abs_exponent - integer_part;\n\n        val result = 1.0f;\n        val temp = this;\n\n        val i = 0;\n        while i < integer_part {\n            result = result * temp;\n            i = i + 1;\n        }\n\n        if fractional_part > 0 {\n            result = result * this.sqrt().pow(fractional_part * 2);\n        }\n\n        if is_exponent_negative {\n            result = 1.0f / result;\n        }\n\n        return result;\n    }\n}"
  },
  {
    "path": "lib/aria/numerics/float/trig.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Float {\n    func sin() {\n        val τ = Float.π*2;\n        val ε = 0.000000000001f;\n        val x = this % τ;\n        if x > Float.π {\n            x -= τ;\n        }\n\n        val term = x;\n        val result = term;\n        val n = 1;\n\n        while term.abs() > ε {\n            n += 2;\n            term = term * (-x * x / (n * (n - 1)));\n            result = result + term;\n        }\n\n        return result;\n    }\n\n    func cos() {\n        val τ = Float.π*2;\n        val ε = 0.000000000001f;\n        val x = this % τ;\n        if x > Float.π {\n            x -= τ;\n        }\n\n        val term = 1.0f;\n        val result = term;\n        val n = 0;\n\n        while term.abs() > ε {\n            n += 2;\n            term = term * (-x * x / (n * (n - 1)));\n            result = result + term;\n        }\n\n        return result;\n    }\n\n    func tan() {\n        return this.sin() / this.cos();\n    }\n\n    func arcsin() {\n        if this < -1.0f || this > 1.0f {\n            throw Float.DomainError.new(\"not a valid sine value\");\n        }\n\n        val ε = 0.000000000001f;\n        val x = this;\n        \n        val term = x;\n        val result = term;\n        val n = 1;\n\n        while term.abs() > ε {\n            term = term * (x * x * (2 * n - 1) * (2 * n - 1)) / ((2 * n) * (2 * n + 1));\n            result = result + term;\n            n += 1;\n        }\n\n        return result;\n    }\n    \n    func arccos() {\n        if this < -1.0f || this > 1.0f {\n            throw Float.DomainError.new(\"not a valid cosine value\");\n        }\n\n        return Float.π / 2 - this.arcsin();\n    }\n\n    func arctan() {\n        val ε = 0.000000000001f;\n        val x = this;\n        if x == -1.0f {\n            return -Float.π / 4;\n        }\n\n        if x == 1.0f {\n            return Float.π / 4;\n        }\n\n        if x.abs() > 1.0f {\n            if x > 0.0f {\n                return Float.π / 2 - (1.0f / x).arctan();\n            } else {\n                return -Float.π / 2 - (1.0f / x).arctan();\n            }\n        }\n\n        if x.abs() > 0.5f {\n            val y = (x - 1) / (x + 1);\n            return Float.π / 4 + y.arctan();\n        }\n\n        val term = x;\n        val result = term;\n        val n = 1;\n\n        while term.abs() > ε {\n            n += 2;\n            term = term * (-x * x * (n - 2) / n);\n            result = result + term;\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "lib/aria/numerics/int/pow.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Int {\n    func pow(y: Int) {\n        if y < 0 {\n            throw Int.DomainError.new(\"Negative exponent not supported\");\n        }\n\n        if y == 0 { return 1; }\n        if this == 0 { return 0; }\n\n        val base = this;\n        val exp = y;\n        val res = 1;\n\n        while exp > 0 {\n            if exp % 2 != 0 {\n                res *= base;\n            }\n            if exp == 1 { break; }\n            base *= base;\n            exp /= 2;\n        }\n\n        return res;\n    }\n}\n"
  },
  {
    "path": "lib/aria/numerics/matrix.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport CompareResult, TotalOrdering from aria.ordering.compare;\nimport Map from aria.structures.map;\nimport Range from aria.range.range;\n\nstruct MatrixIndex {\n    type func new(row: Int, col: Int) {\n        return alloc(This) {\n            .row = row,\n            .col = col,\n        };\n    }\n\n    func hash() {\n        return this.row * 31 + this.col;\n    }\n\n    operator ==(other) {\n        return this.row == other.row && this.col == other.col;\n    }\n}\n\nstruct Matrix {\n    struct DimensionMismatch {\n        type func new(msg: String) {\n            return alloc(This) {\n                .msg = msg,\n            };\n        }\n\n        func prettyprint() {\n            return \"DimensionMismatch: \" + this.msg;\n        }\n    }\n\n    type func new(rows: Int, cols: Int) {\n        return alloc(This) {\n            .rows = rows,\n            .cols = cols,\n            .data = Map.new(),\n        };\n    }\n\n    func get(row: Int, col: Int) {\n        if row >= this.rows || col >= this.cols {\n            throw Matrix.DimensionMismatch.new(\"Index out of bounds: ({0},{1})\".format(row, col));\n        }\n\n        match this.data.get(MatrixIndex.new(row, col)) {\n            case Some(value) => {\n                return value;\n            }\n        } else {\n            # ideally, we would find the type of (0,0) and default to it\n            # and only return float if 0,0 is missing (or a float)\n            return 0.0f;\n        }\n    }\n\n    operator[](row: Int, col: Int) {\n        return this.get(row, col);\n    }\n\n    func set(row: Int, col: Int, value) {\n        if row >= this.rows || col >= this.cols {\n            throw Matrix.DimensionMismatch.new(\"Index out of bounds: ({0},{1})\".format(row, col));\n        }\n\n        this.data.set(MatrixIndex.new(row, col), value);\n    }\n\n    operator[]=(row: Int, col: Int, value) {\n        this.set(row, col, value);\n    }\n\n    operator +(other: Matrix) {\n        if (this.rows != other.rows || this.cols != other.cols) {\n            throw Matrix.DimensionMismatch.new(\"Matrix dimensions do not match for addition\");\n        }\n\n        val result = Matrix.new(this.rows, this.cols);\n        for row in Range.from(0).to(this.rows) {\n            for col in Range.from(0).to(this.cols) {\n                result.set(row, col, this.get(row, col) + other.get(row, col));\n            }\n        }\n\n        return result;\n    }\n\n    operator ==(other: Matrix) {\n        if (this.rows != other.rows || this.cols != other.cols) {\n            return false;\n        }\n\n        for row in Range.from(0).to(this.rows) {\n            for col in Range.from(0).to(this.cols) {\n                if this.get(row, col) != other.get(row, col) {\n                    return false;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    operator -(other: Matrix) {\n        if (this.rows != other.rows || this.cols != other.cols) {\n            throw Matrix.DimensionMismatch.new(\"Matrix dimensions do not match for subtraction\");\n        }\n\n        val result = Matrix.new(this.rows, this.cols);\n        for row in Range.from(0).to(this.rows) {\n            for col in Range.from(0).to(this.cols) {\n                result.set(row, col, this.get(row, col) - other.get(row, col));\n            }\n        }\n\n        return result;\n    }\n\n    func transpose() {\n        val result = Matrix.new(this.cols, this.rows);\n        for row in Range.from(0).to(this.rows) {\n            for col in Range.from(0).to(this.cols) {\n                result.set(col, row, this.get(row, col));\n            }\n        }\n        return result;\n    }\n\n    func prettyprint() {\n        val ret = [];\n        for row in Range.from(0).to(this.rows) {\n            val row_str = [];\n            for col in Range.from(0).to(this.cols) {\n                row_str.append(this.get(row, col));\n            }\n            ret.append(\"[\" + row_str.join() + \"]\");\n        }\n        return \"Matrix(\" + ret.join() + \")\";\n    }\n\n    operator *(other: Matrix) {\n        if (this.cols != other.rows) {\n            throw Matrix.DimensionMismatch.new(\"Matrix dimensions do not match for multiplication\");\n        }\n\n        val result = Matrix.new(this.rows, other.cols);\n        for row in Range.from(0).to(this.rows) {\n            for col in Range.from(0).to(other.cols) {\n                val sum = alloc(typeof(this.get(0,0)));\n                for k in Range.from(0).to(this.cols) {\n                    sum += this.get(row, k) * other.get(k, col);\n                }\n                result.set(row, col, sum);\n            }\n        }\n\n        return result;\n    }\n\n    func determinant() {\n        if (this.rows != this.cols) {\n            throw Matrix.DimensionMismatch.new(\"Determinant can only be calculated for square matrices\");\n        }\n\n        val n = this.rows;\n\n        if n == 1 {\n            return this.get(0, 0);\n        } elsif n == 2 {\n            return this.get(0, 0) * this.get(1, 1) - this.get(0, 1) * this.get(1, 0);\n        }\n\n        val work = Matrix.new(n, n);\n        for row in Range.from(0).to(n) {\n            for col in Range.from(0).to(n) {\n                work.set(row, col, this.get(row, col) * 1.0f);\n            }\n        }\n\n        val det = 1.0f;\n        val sign = 1.0f;\n\n        for col in Range.from(0).to(n) {\n            val pivot_row = col;\n            val pivot_val = work.get(col, col);\n            if pivot_val < 0.0f {\n                pivot_val = -pivot_val;\n            }\n\n            for row in Range.from(col + 1).to(n) {\n                val abs_val = work.get(row, col);\n                if abs_val < 0.0f {\n                    abs_val = -abs_val;\n                }\n                if abs_val > pivot_val {\n                    pivot_val = abs_val;\n                    pivot_row = row;\n                }\n            }\n\n            if pivot_val == 0.0f {\n                return 0.0f;\n            }\n\n            if pivot_row != col {\n                for k in Range.from(0).to(n) {\n                    val temp = work.get(col, k);\n                    work.set(col, k, work.get(pivot_row, k));\n                    work.set(pivot_row, k, temp);\n                }\n                sign = -sign;\n            }\n\n            val pivot = work.get(col, col);\n\n            for row in Range.from(col + 1).to(n) {\n                val factor = work.get(row, col) / pivot;\n                for k in Range.from(col).to(n) {\n                    work.set(row, k, work.get(row, k) - factor * work.get(col, k));\n                }\n            }\n        }\n\n        for i in Range.from(0).to(n) {\n            det *= work.get(i, i);\n        }\n\n        return det * sign;\n    }\n}\n"
  },
  {
    "path": "lib/aria/ordering/compare.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum CompareResult {\n    case lt,\n    case eq,\n    case gt,\n}\n\nmixin TotalOrdering {\n    # requires func comp(this,x) that returns a CompareResult\n\n    operator ==(rhs) {\n        match this.comp(rhs) {\n            isa CompareResult and case eq => {\n                return true;\n            }\n        } else {\n            return false;\n        }\n    }\n\n    operator < (rhs) {\n        match this.comp(rhs) {\n            isa CompareResult and case lt => {\n                return true;\n            }\n        } else {\n            return false;\n        }\n    }\n\n    operator > (rhs) {\n        match this.comp(rhs) {\n            isa CompareResult and case gt => {\n                return true;\n            }\n        } else {\n            return false;\n        }\n    }\n\n    operator <= (rhs) {\n        match this.comp(rhs) {\n            isa CompareResult and case lt => {\n                return true;\n            },\n            isa CompareResult and case eq => {\n                return true;\n            }\n        } else {\n            return false;\n        }\n    }\n\n    operator >= (rhs) {\n        match this.comp(rhs) {\n            isa CompareResult and case gt => {\n                return true;\n            },\n            isa CompareResult and case eq => {\n                return true;\n            }\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/ordering/utils.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport CompareResult from aria.ordering.compare;\n\nfunc min(l: List) {\n    val min = l[0];\n\n    for i in l {\n        if i < min {\n            min = i;\n        }\n    }\n\n    return min;\n}\n\nfunc min_with_comparator(l: List, cmp) {\n    val min = l[0];\n\n    for i in l {\n        if cmp(i, min).is_lt() {\n            min = i;\n        }\n    }\n\n    return min;\n}\n\nfunc max(l: List) {\n    val max = l[0];\n\n    for i in l {\n        if i > max {\n            max = i;\n        }\n    }\n\n    return max;\n}\n\nfunc max_with_comparator(l: List, cmp) {\n    val max = l[0];\n\n    for i in l {\n        if cmp(i, max).is_gt() {\n            max = i;\n        }\n    }\n\n    return max;\n}\n\nfunc min_max(l: List) {\n    val min = l[0];\n    val max = l[0];\n\n    for i in l {\n        if i < min {\n            min = i;\n        }\n        if i > max {\n            max = i;\n        }\n    }\n\n    return Box(){\n        .min = min,\n        .max = max\n    };\n}\n\nfunc min_max_with_comparator(l: List, cmp) {\n    val min = l[0];\n    val max = l[0];\n\n    for i in l {\n        if cmp(i, min).is_lt() {\n            min = i;\n        }\n        if cmp(i, max).is_gt() {\n            max = i;\n        }\n    }\n\n    return Box(){\n        .min = min,\n        .max = max\n    };\n}\n"
  },
  {
    "path": "lib/aria/range/int_extension.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nextension Int {\n    func to(n: Int) {\n        return Range.from(this).to(n);\n    }\n    \n    func through(n: Int) {\n        return Range.from(this).through(n);\n    }\n}\n"
  },
  {
    "path": "lib/aria/range/range.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Iterator,Iterable from aria.iterator.mixin;\n\nstruct InvalidRangeError {\n    type func new(msg: String) = alloc(This) {.msg};\n\n    func prettyprint() {\n        return \"range error: {0}\".format(this.msg);\n    }\n}\n\nstruct RangeIterator {\n    type func new(from, to, step) {\n        if step == 0 {\n            throw InvalidRangeError.new(\"iteration step cannot be zero\");\n        }\n\n        val cur = from;\n        val lim = to;\n\n        if step < 0 {\n            cur = to - 1;\n            lim = from - 1;\n        }\n\n        return alloc(This) {\n            .current = cur,\n            .limit = lim,\n            .step = step,\n        };\n    }\n\n    func next() {\n        if this.step > 0 {\n            if this.current >= this.limit {\n                return Maybe::None;\n            }\n        } else {\n            if this.current <= this.limit {\n                return Maybe::None;\n            }\n        }\n\n        val result = this.current;\n        this.current += this.step;\n        return Maybe::Some(result);\n    }\n\n    include Iterator\n}\n\nstruct RangeImpl {\n    type func new(from, to) = alloc(This) {.from, .to};\n\n    func step(n) {\n        return RangeIterator.new(this.from, this.to, n);\n    }\n\n    func iterator() {\n        return this.step(1);\n    }\n\n    func descending() {\n        return this.step(-1);\n    }\n\n    func contains(x) {\n        return x >= this.from && x < this.to;\n    }\n\n    func length() {\n        return this.to - this.from;\n    }\n\n    func union(other) {\n        val lo = other.from < this.from ? other.from : this.from;\n        val hi = other.to > this.to ? other.to : this.to;\n        return RangeImpl.new(lo, hi);\n    }\n\n    func intersection(other) {\n        val lo = other.from > this.from ? other.from : this.from;\n        val hi = other.to < this.to ? other.to : this.to;\n        return lo >= hi ? RangeImpl.new(0, 0) : RangeImpl.new(lo, hi);\n    }\n\n    include Iterable\n\n    func prettyprint() {\n        return \"Range from={0} to={1}\".format(this.from, this.to);\n    }\n\n    func hash() {\n        val h = this.from ^ (this.to + 0x9e3779b97f4a7c15);\n        h = h ^ (h >> 30);\n        h = h * 0xbf58476d1ce4e5b9;\n        h = h ^ (h >> 27);\n        h = h * 0x94d049bb133111eb;\n        h = h ^ (h >> 31);\n        return h;\n    }\n\n    operator == (other: RangeImpl) {\n        return this.from == other.from && this.to == other.to;\n    }\n}\n\nstruct RangeFrom {\n    type func new(n) {\n        return alloc(This) {\n            .from = n,\n        };\n    }\n\n    func to(n) {\n        if this.from > n {\n            throw InvalidRangeError.new(\"lower bound {0} is greater than upper bound {1}\".format(this.from, n));\n        }\n        return RangeImpl.new(this.from, n);\n    }\n\n    func through(n) {\n        if this.from > n {\n            throw InvalidRangeError.new(\"lower bound {0} is greater than upper bound {1}\".format(this.from, n));\n        }\n        return RangeImpl.new(this.from, n+1); # inclusive range - end at n + 1\n    }\n}\n\nstruct Range {\n    type func from(n) {\n        return RangeFrom.new(n);\n    }\n}\n"
  },
  {
    "path": "lib/aria/rng/mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin RngRange {\n    # assume the Rng has instance func next()\n\n    func in_range(low, high) {\n        val range = high - low + 1;\n        val n = this.next();\n        return low + ((n % range + range) % range);\n    }\n\n    func one_of(x: List) {\n        if x.len() == 0 {\n            throw RuntimeError::OperationFailed(\"cannot choose from empty list\");\n        }\n        val low = 0;\n        val high = x.len() - 1;\n        val index = this.in_range(low, high);\n        return x[index];\n    }\n}\n"
  },
  {
    "path": "lib/aria/rng/msws.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.rng.mixin;\n\nstruct MiddleSquareRng {\n    type func new() {\n        return MiddleSquareRng.new_with_params(now(),0x5ad4eceda1ce2a9);\n    }\n\n    type func new_with_params(x,s) = alloc(This){\n        .x,\n        .w = 0,\n        .s,\n    };\n\n    func next() {\n        this.x = this.x * this.x;\n        this.w += this.s;\n        this.x += this.w;\n        this.x = (this.x >> 32) | (this.x << 32);\n        return this.x;\n    }\n\n    include aria.rng.mixin.RngRange\n}\n"
  },
  {
    "path": "lib/aria/rng/xorshift.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.rng.mixin;\n\nstruct XorshiftRng {\n    type func new() {\n        return XorshiftRng.new_with_seed(now());\n    }\n\n    type func new_with_seed(seed) {\n        return alloc(This) {\n            .x = seed | 1\n        };\n    }\n\n    func next() {\n        this.x = this.x ^ (this.x << 7);\n        this.x = this.x ^ (this.x >> 9);\n        return this.x;\n    }\n\n    include aria.rng.mixin.RngRange\n}\n"
  },
  {
    "path": "lib/aria/string/classes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_unicode\");\n\nextension String {\n    func is_letter() = this.is_lowercase_letter() || this.is_uppercase_letter();\n\n    func is_alphanumeric() = this.is_letter() || this.is_digit();\n}\n"
  },
  {
    "path": "lib/aria/string/regex.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_regex\");\n\nstruct Regex {\n    struct Match {\n        func prettyprint() {\n            return 'match(start={0} len={1} val=\"{2}\")'.format(this.start, this.len, this.value);\n        }\n    }\n\n    struct Error {\n        type func new(msg: String) {\n            return alloc(This) {.msg = msg};\n        }\n\n        func prettyprint() {\n            return \"regex error: {0}\".format(this.msg);\n        }\n    }\n\n    func prettyprint() {\n        return 'Regex(\"{0}\")'.format(this.pattern);\n    }\n}\n"
  },
  {
    "path": "lib/aria/structures/hash/algo/sip.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc rotl64(x,r) = ((x << r) | (x >> (64 - r)));\n\nfunc load_le_u64(p) = p[0]\n    | (p[1] << 8)\n    | (p[2] << 16)\n    | (p[3] << 24)\n    | (p[4] << 32)\n    | (p[5] << 40)\n    | (p[6] << 48)\n    | (p[7] << 56);\n\nstruct SipHasher {\n    type func new(k0: Int, k1: Int) = alloc(This) {\n        .k0,\n        .k1,\n        .v0 = k0 ^ 0x736f6d6570736575,\n        .v1 = k1 ^ 0x646f72616e646f6d,\n        .v2 = k0 ^ 0x6c7967656e657261,\n        .v3 = k1 ^ 0x7465646279746573,\n        .len = 0,\n        .buf = [0,0,0,0,0,0,0,0],\n        .buflen = 0,\n    };\n\n    func sip_round() {\n        this.v0 = this.v0 + this.v1;\n        this.v1 = rotl64(this.v1, 13);\n        this.v1 = this.v1 ^ this.v0;\n        this.v0 = rotl64(this.v0, 32);\n\n        this.v2 = this.v2 + this.v3;\n        this.v3 = rotl64(this.v3, 16);\n        this.v3 = this.v3 ^ this.v2;\n\n        this.v0 = this.v0 + this.v3;\n        this.v3 = rotl64(this.v3, 21);\n        this.v3 = this.v3 ^ this.v0;\n\n        this.v2 = this.v2 + this.v1;\n        this.v1 = rotl64(this.v1, 17);\n        this.v1 = this.v1 ^ this.v2;\n        this.v2 = rotl64(this.v2, 32);\n\n        return this;\n    }\n\n    func compress(m) {\n        this.v3 = this.v3 ^ m;\n        this.sip_round();\n        this.v0 = this.v0 ^ m;\n    }\n\n    func write(data) {\n        if !(data isa List) {\n            data = [data];\n        }\n\n        val i = 0;\n\n        if this.buflen > 0 {\n            while i < data.len() && this.buflen < 8 {\n                this.buf[this.buflen] = data[i];\n                this.buflen += 1;\n                i += 1;\n            }\n            if this.buflen == 8 {\n                this.compress(load_le_u64(this.buf));\n                this.buflen = 0;\n            }\n        }\n\n        while i + 8 <= data.len() {\n            val m8 = [0,0,0,0,0,0,0,0];\n            m8[0] = data[i+0]; m8[1] = data[i+1]; m8[2] = data[i+2]; m8[3] = data[i+3];\n            m8[4] = data[i+4]; m8[5] = data[i+5]; m8[6] = data[i+6]; m8[7] = data[i+7];\n            val m = load_le_u64(m8);\n            this.compress(m);\n            i += 8;\n        }\n\n        while i < data.len() {\n            this.buf[this.buflen] = data[i];\n            this.buflen += 1;\n            i += 1;\n        }\n        this.len += data.len();\n\n        return this;\n    }\n\n    func finish() {\n        val b = this.len << 56;\n        val i = 0;\n\n        while i < this.buflen {\n            b = b | this.buf[i] << (8 * i);\n            i += 1;\n        }\n\n        this.v3 = this.v3 ^ b;\n\n        this.sip_round();\n        this.v0 = this.v0 ^ b;\n\n        this.v2 = this.v2 ^ 0xff;\n\n        this.sip_round().sip_round().sip_round();\n\n        return (this.v0 ^ this.v1) ^ (this.v2 ^ this.v3);\n    }\n}\n"
  },
  {
    "path": "lib/aria/structures/hash/list.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport SipHasher from aria.structures.hash.algo.sip;\n\nextension List {\n    func hash() {\n        val hasher = SipHasher.new(0x0706050403020100, 0x0f0e0d0c0b0a0908);\n        for item in this {\n            # TODO: runtime error, skip non-hashable items?\n            hasher.write(item.hash());\n        }\n        return hasher.finish();\n    }\n}\n"
  },
  {
    "path": "lib/aria/structures/map.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Iterator,Iterable from aria.iterator.mixin;\n\nstruct Map {\n    type val DEFAULT_CAPACITY = 128;\n\n    struct Entry {\n        type func new(key, value) = alloc(This) {.key, .value};\n    }\n\n    func calc_hash(k) {\n        val h = k.hash();\n        val n = this.capacity;\n        return ((h % n) + n) % n;\n    }\n\n    type func new() {\n        return Map.new_with_capacity(Map.DEFAULT_CAPACITY);\n    }\n\n    type func new_with_capacity(capacity: Int) {\n        if capacity <= 0 {\n            capacity = Map.DEFAULT_CAPACITY;\n        }\n\n        return alloc(This) {\n            .buckets = List.from_function(|_| => [], capacity),\n            .count = 0,\n            .capacity,\n        };\n    }\n\n    type func frequency_map(iter) {\n        val this = This.new();\n        for item in iter {\n            val count = this.get(item) ?? 0;\n            this.set(item, count + 1);\n        }\n        return this;\n    }\n\n    func load_factor() {\n        return (this.count * 1.0f) / (this.capacity * 1.0f);\n    }\n\n    func resize(new_capacity: Int) {\n        val old_buckets = this.buckets;\n        this.buckets = List.from_function(|_| => [], new_capacity);\n        this.capacity = new_capacity;\n        this.count = 0;\n\n        for bucket in old_buckets {\n            for entry in bucket {\n                if entry isa Map.Entry {\n                    this.set(entry.key, entry.value);\n                }\n            }\n        }\n    }\n\n    func keys() {\n        val remaining = this.len();\n        val ret = [];\n        val buckets_len = this.buckets.len();\n        for bucket in this.buckets {\n            for entry in bucket {\n                if entry isa Map.Entry {\n                    ret.append(entry.key);\n                    remaining -= 1;\n                    if remaining == 0 {\n                        return ret;\n                    }\n                }\n            }\n        }\n\n        assert remaining == 0;\n        return ret;\n    }\n\n    func prettyprint() {\n        val first = true;\n        val ret = \"\";\n        val count = this.len();\n        for bucket in this.buckets {\n            for entry in bucket {\n                if entry isa Map.Entry {\n                    if first {\n                        ret = \"[{0}]->{1}\".format(entry.key, entry.value);\n                        first = false;\n                    } else {\n                        ret = ret + \", [{0}]->{1}\".format(entry.key, entry.value);\n                    }\n                    count -= 1;\n                    if count == 0 {\n                        return \"Map(\" + ret + \")\";\n                    }\n                }\n            }\n        }\n\n        return \"Map(\" + ret + \")\";\n    }\n\n    func set(k,v) {\n        if this.load_factor() > 0.7f {\n            this.resize(this.capacity * 2);\n        }\n\n        val h = this.calc_hash(k);\n        val bucket = this.buckets[h];\n        val bucket_len = bucket.len();\n        val idx = 0;\n        val need_append = true;\n        val len_increase = true;\n        while idx < bucket_len {\n            match bucket[idx] {\n                isa Map.Entry => {\n                    if bucket[idx].key == k {\n                        len_increase = false; # key overwrite does not increase len\n                        bucket[idx].value = v;\n                        need_append = false;\n                        break;\n                    }\n                },\n                isa Maybe => {\n                    bucket[idx] = Map.Entry.new(k,v);\n                    need_append = false;\n                    break;\n                }\n            }\n            idx = idx + 1;\n        }\n        if need_append {\n            bucket.append(Map.Entry.new(k,v));\n        }\n        if len_increase {\n            this.count += 1;\n        }\n\n        return len_increase;\n    }\n\n    func remove(k) {\n        val h = this.calc_hash(k);\n        val bucket = this.buckets[h];\n        val bucket_len = bucket.len();\n        val idx = 0;\n        while idx < bucket_len {\n            match bucket[idx] {\n                isa Map.Entry => {\n                    if bucket[idx].key == k {\n                        assert this.count > 0;\n                        this.count -= 1;\n                        bucket[idx] = Maybe::None;\n                        return true;\n                    }\n                }\n            }\n            idx = idx + 1;\n        }\n\n        return false;\n    }\n\n    func get(k) {\n        val h = this.calc_hash(k);\n        val bucket = this.buckets[h];\n        val bucket_len = bucket.len();\n        for entry in bucket {\n            if (entry isa Map.Entry) && entry.key == k {\n                return Maybe::Some(entry.value);\n            }\n        }\n        return Maybe::None;\n    }\n\n    func contains(k) {\n        return this.get(k).is_Some();\n    }\n\n    func len() {\n        return this.count;\n    }\n\n    operator [](k) {\n        return this.get(k).unwrap_Some();\n    }\n\n    operator []=(k,v) {\n        return this.set(k,v);\n    }\n\n    struct MapIterator {\n        type func new(m: Map) {\n            return alloc(This){\n                .buckets = m.buckets,\n                .bucket_idx = 0,\n                .entry_idx = 0,\n            };\n        }\n\n        func next() {\n            val buckets = this.buckets;\n            val num_buckets = buckets.len();\n            \n            while this.bucket_idx < num_buckets {\n                val bucket = buckets[this.bucket_idx];\n                while this.entry_idx < bucket.len() {\n                    val entry = bucket[this.entry_idx];\n                    this.entry_idx += 1;\n                    if entry isa Map.Entry {\n                        return Maybe::Some(Box(){ .key = entry.key, .value = entry.value });\n                    }\n                }\n                this.bucket_idx += 1;\n                this.entry_idx = 0;\n            }\n            \n            return Maybe::None;\n        }\n\n        include Iterator\n    }\n\n    func iterator() {\n        return Map.MapIterator.new(this);\n    }\n\n    include Iterable\n}\n"
  },
  {
    "path": "lib/aria/structures/queue.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct PriorityQueue {\n    type func new() = This.new_with_comparator(|x,y| => x < y);\n\n    type func new_with_comparator(cmp) = alloc(This) {\n        .data = [],\n        .cmp,\n    };\n\n    func push(item) {\n        this.data.append(item);\n        this._sift_up(this.data.len() - 1);\n    }\n\n    func pop() {\n        val top = this.data[0];\n        val last = this.data.drop();\n        if this.data.len() > 0 {\n            this.data[0] = last;\n            this._sift_down(0);\n        }\n        return top;\n    }\n\n    func peek() {\n        return this.data.len() == 0 ? Maybe::None : Maybe::Some(this.data[0]);\n    }\n\n    func len() {\n        return this.data.len();\n    }\n\n    func _sift_up(index) {\n        val i = index;\n        while i > 0 {\n            val parent = (i - 1) / 2;\n            if this.cmp(this.data[i], this.data[parent]) {\n                val tmp = this.data[i];\n                this.data[i] = this.data[parent];\n                this.data[parent] = tmp;\n                i = parent;\n            } else {\n                break;\n            }\n        }\n    }\n\n    func _sift_down(index) {\n        val i = index;\n        val n = this.data.len();\n        while true {\n            val left = 2 * i + 1;\n            val right = 2 * i + 2;\n            val smallest = i;\n\n            if left < n && this.cmp(this.data[left], this.data[smallest]) {\n                smallest = left;\n            }\n\n            if right < n && this.cmp(this.data[right], this.data[smallest]) {\n                smallest = right;\n            }\n\n            if smallest == i {\n                break;\n            }\n\n            val tmp = this.data[i];\n            this.data[i] = this.data[smallest];\n            this.data[smallest] = tmp;\n\n            i = smallest;\n        }\n    }\n}"
  },
  {
    "path": "lib/aria/structures/set.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nstruct Set {\n    type func new() = alloc(This) {\n        .impl = Map.new(),\n    };\n\n    type func new_with_items(...) {\n        val ret = Set.new();\n        for item in varargs {\n            ret.set(item);\n        }\n        return ret;\n    }\n\n    func set(x) {\n        this.impl.set(x, true);\n    }\n\n    func contains(x) {\n        return this.impl.contains(x);\n    }\n\n    func remove(x) {\n        this.impl.remove(x);\n    }\n\n    func len() {\n        return this.impl.len();\n    }\n\n    func union(other) {\n        val ret = Set.new();\n        for x in this {\n            ret.set(x);\n        }\n        for x in other {\n            ret.set(x);\n        }\n        return ret;\n    }\n\n    func intersection(other) {\n        val ret = Set.new();\n        for x in this {\n            if other.contains(x) {\n                ret.set(x);\n            }\n        }\n        return ret;\n    }\n\n    func difference(other) {\n        val ret = Set.new();\n        for x in this {\n            if !other.contains(x) {\n                ret.set(x);\n            }\n        }\n        return ret;\n    }\n\n    struct SetIterator {\n        type func new(set) {\n            return alloc(This) {\n                .impl = set.impl.iterator(),\n            };\n        }\n\n        func next() {\n            val nv = this.impl.next();\n            return Maybe::Some(nv?.key);\n        }\n    }\n\n    func iterator() {\n        return Set.SetIterator.new(this);\n    }\n}\n"
  },
  {
    "path": "lib/aria/structures/stack.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nstruct Stack {\n    type func new() = alloc(This) {\n        .store = [],\n        .count = 0,\n    };\n\n    func len() {\n        return this.count;\n    }\n\n    func is_empty() {\n        return this.count == 0;\n    }\n\n    func push(x) {\n        if this.count == this.store.len() {\n            this.store.append(x);\n        } else {\n            this.store[this.count] = x;\n        }\n        this.count += 1;\n    }\n\n    func peek_at(offset) {\n        if offset >= this.count {\n            return Maybe::None;\n        } else {\n            return Maybe::Some(this.store[this.count - 1 - offset]);\n        }\n    }\n\n    func peek() {\n        return this.peek_at(0);\n    }\n\n    func try_pop() {\n        val p = this.peek();\n        match p {\n            case Some => {\n                assert this.count > 0;\n                this.count -= 1;\n            }\n        }\n        return p;\n    }\n\n    func pop() {\n        return this.try_pop().unwrap_Some();\n    }\n}\n"
  },
  {
    "path": "lib/aria/system/coloring.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Color {\n    case Black,\n    case Red,\n    case Green,\n    case Yellow,\n    case Blue,\n    case Magenta,\n    case Cyan,\n    case White,\n    case BrightBlack,\n    case BrightRed,\n    case BrightGreen,\n    case BrightYellow,\n    case BrightBlue,\n    case BrightMagenta,\n    case BrightCyan,\n    case BrightWhite,\n\n    struct RGB {\n        type func new(red: Int, green: Int, blue: Int) {\n            if red < 0 {\n                red *= -1;\n            }\n            if green < 0 {\n                green *= -1;\n            }\n            if blue < 0 {\n                blue *= -1;\n            }\n\n            red = red % 256;\n            green = green % 256;\n            blue = blue % 256;\n\n            return alloc(This) {\n                .red,\n                .green,\n                .blue\n            };\n        }\n\n        type func new_with_hex_string(s: String) {\n            if s.len() == 7 && s[0] == '#' {\n                s = s.substring(1, s.len());\n            }\n\n            if s.len() != 6 {\n                return Result::Err(\"Invalid RGB hex string length\");\n            }\n\n            val red = s.substring(0,1);\n            val green = s.substring(2,3);\n            val blue = s.substring(4,5);\n\n            val red = Int.parse_radix(red, 16)?;\n            val green = Int.parse_radix(green, 16)?;\n            val blue = Int.parse_radix(blue, 16)?;\n\n            return Result::Ok(This.new(red, green, blue));\n        }\n\n        func prettyprint() {\n            return \"RGB({0}, {1}, {2})\".format(this.red, this.green, this.blue);\n        }\n\n        func to_ansi_sequence() {\n            return \"2;{0};{1};{2}\".format(this.red, this.green, this.blue);\n        }\n    }\n\n    case RGB(Color.RGB),\n}\n\nextension Color {\n    func prettyprint() {\n        match this {\n            case Black => { return \"Black\"; },\n            case Red => { return \"Red\"; },\n            case Green => { return \"Green\"; },\n            case Yellow => { return \"Yellow\"; },\n            case Blue => { return \"Blue\"; },\n            case Magenta => { return \"Magenta\"; },\n            case Cyan => { return \"Cyan\"; },\n            case White => { return \"White\"; },\n            case BrightBlack => { return \"Bright Black\"; },\n            case BrightRed => { return \"Bright Red\"; },\n            case BrightGreen => { return \"Bright Green\"; },\n            case BrightYellow => { return \"Bright Yellow\"; },\n            case BrightBlue => { return \"Bright Blue\"; },\n            case BrightMagenta => { return \"Bright Magenta\"; },\n            case BrightCyan => { return \"Bright Cyan\"; },\n            case BrightWhite => { return \"Bright White\"; },\n            case RGB(r) => { return r.prettyprint(); },\n        }\n    }\n}\n\nextension Color {\n    func to_ansi_sequence(fg: Bool) {\n        match this {\n            case Black => { return fg ? \"30\" : \"40\"; },\n            case Red => { return fg ? \"31\" : \"41\"; },\n            case Green => { return fg ? \"32\" : \"42\"; },\n            case Yellow => { return fg ? \"33\" : \"43\"; },\n            case Blue => { return fg ? \"34\" : \"44\"; },\n            case Magenta => { return fg ? \"35\" : \"45\"; },\n            case Cyan => { return fg ? \"36\" : \"46\"; },\n            case White => { return fg ? \"37\" : \"47\"; },\n            case BrightBlack => { return fg ? \"90\" : \"100\"; },\n            case BrightRed => { return fg ? \"91\" : \"101\"; },\n            case BrightGreen => { return fg ? \"92\" : \"102\"; },\n            case BrightYellow => { return fg ? \"93\" : \"103\"; },\n            case BrightBlue => { return fg ? \"94\" : \"104\"; },\n            case BrightMagenta => { return fg ? \"95\" : \"105\"; },\n            case BrightCyan => { return fg ? \"96\" : \"106\"; },\n            case BrightWhite => { return fg ? \"97\" : \"107\"; },\n            case RGB(r) => {\n                val color_seq = r.to_ansi_sequence();\n                return \"{0};{1}\".format(fg ? 38 : 48, color_seq);\n            }\n        }\n    }\n}\n\nstruct ColorScheme {\n    type func new() = alloc(This).reset();\n\n    func reset() {\n        this.bold = false;\n        this.fg = Maybe::None;\n        this.bg = Maybe::None;\n        return this;\n    }\n\n    func with_background_color(c: Color) {\n        this.bg = Maybe::Some(c);\n        return this;\n    }\n\n    func with_foreground_color(c: Color) {\n        this.fg = Maybe::Some(c);\n        return this;\n    }\n\n    func with_bold(b: Bool) {\n        this.bold = b;\n        return this;\n    }\n\n    func apply(s: String) {\n        val result = s;\n        val flags_on = [];\n        val flags_off = [];\n\n        if this.bold {\n            flags_on.append(\"1\");\n            flags_off.append(\"22\");\n        }\n\n        match this.fg {\n            case Some(c) => {\n                flags_on.append(c.to_ansi_sequence(true));\n                flags_off.append(\"39\");\n            },\n        }\n\n        match this.bg {\n            case Some(c) => {\n                flags_on.append(c.to_ansi_sequence(false));\n                flags_off.append(\"49\");\n            },\n        }\n\n        assert flags_on.len() == flags_off.len();\n\n        if flags_on.len() == 0 {\n            return result;\n        } else {\n            return \"\\x1b[{0}m{1}\\x1b[{2}m\".format(\";\".join(flags_on), result, \";\".join(flags_off));\n        }\n    }\n\n    func prettyprint() {\n        val fg_string = \"foreground: default\";\n        match this.fg {\n            case Some(c) => { fg_string = \"foreground: \" + c.prettyprint(); },\n        }\n\n        val bg_string = \"background: default\";\n        match this.bg {\n            case Some(c) => { bg_string = \"background: \" + c.prettyprint(); },\n        }\n\n        val bold_string = this.bold ? \"bold: on\" : \"bold: off\";\n\n        return \"color scheme: \" + fg_string + \" \" + bg_string + \" \" + bold_string;\n    }\n}\n\nextension String {\n    func with_background_color(c: Color) {\n        return \"\\x1b[{0}m{1}\\x1b[49m\".format(c.to_ansi_sequence(false), this);\n    }\n\n    func with_foreground_color(c: Color) {\n        return \"\\x1b[{0}m{1}\\x1b[39m\".format(c.to_ansi_sequence(true), this);\n    }\n\n    func with_bold() {\n        return \"\\x1b[1m{0}\\x1b[22m\".format(this);\n    }\n\n    func with_style(s: ColorScheme) {\n        return s.apply(this);\n    }\n\n    func black() = this.with_foreground_color(Color::Black);\n    func red() = this.with_foreground_color(Color::Red);\n    func green() = this.with_foreground_color(Color::Green);\n    func yellow() = this.with_foreground_color(Color::Yellow);\n    func blue() = this.with_foreground_color(Color::Blue);\n    func magenta() = this.with_foreground_color(Color::Magenta);\n    func cyan() = this.with_foreground_color(Color::Cyan);\n    func white() = this.with_foreground_color(Color::White);\n\n    func black_bg() = this.with_background_color(Color::Black);\n    func red_bg() = this.with_background_color(Color::Red);\n    func green_bg() = this.with_background_color(Color::Green);\n    func yellow_bg() = this.with_background_color(Color::Yellow);\n    func blue_bg() = this.with_background_color(Color::Blue);\n    func magenta_bg() = this.with_background_color(Color::Magenta);\n    func cyan_bg() = this.with_background_color(Color::Cyan);\n    func white_bg() = this.with_background_color(Color::White);\n\n    func bright_black() = this.with_foreground_color(Color::BrightBlack);\n    func bright_red() = this.with_foreground_color(Color::BrightRed);\n    func bright_green() = this.with_foreground_color(Color::BrightGreen);\n    func bright_yellow() = this.with_foreground_color(Color::BrightYellow);\n    func bright_blue() = this.with_foreground_color(Color::BrightBlue);\n    func bright_magenta() = this.with_foreground_color(Color::BrightMagenta);\n    func bright_cyan() = this.with_foreground_color(Color::BrightCyan);\n    func bright_white() = this.with_foreground_color(Color::BrightWhite);\n\n    func bright_black_bg() = this.with_background_color(Color::BrightBlack);\n    func bright_red_bg() = this.with_background_color(Color::BrightRed);\n    func bright_green_bg() = this.with_background_color(Color::BrightGreen);\n    func bright_yellow_bg() = this.with_background_color(Color::BrightYellow);\n    func bright_blue_bg() = this.with_background_color(Color::BrightBlue);\n    func bright_magenta_bg() = this.with_background_color(Color::BrightMagenta);\n    func bright_cyan_bg() = this.with_background_color(Color::BrightCyan);\n    func bright_white_bg() = this.with_background_color(Color::BrightWhite);\n}\n"
  },
  {
    "path": "lib/aria/system/platform.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nflag: uses_dylib(\"aria_platform\");\n\nenum Platform {\n    struct LinuxPlatform {\n        type func new(kernel_version: String) {\n            return alloc(This) {\n                .kernel_version = kernel_version\n            };\n        }\n\n        func prettyprint() {\n            return \"Linux kernel version: {0}\".format(this.kernel_version);\n        }\n\n        func name() {\n            return \"Linux\";\n        }\n    }\n\n    struct macOSPlatform {\n        type func new(os_build: String) {\n            return alloc(This) {\n                .os_build = os_build\n            };\n        }\n\n        func prettyprint() {\n            return \"macOS build: {0}\".format(this.os_build);\n        }\n\n        func name() {\n            return \"macOS\";\n        }\n    }\n\n    # code in the native layer relies on the order of these cases\n    # if we ever add or change cases, go update the code in\n    # native-libs/platform/src/lib.rs to match the case numbering\n    case Linux(Platform.LinuxPlatform),\n    case macOS(Platform.macOSPlatform),\n    case Unknown,\n\n    func prettyprint() {\n        match this {\n            case Linux(platform) => {\n                return platform.prettyprint();\n            }\n            case macOS(platform) => {\n                return platform.prettyprint();\n            }\n            case Unknown => {\n                return \"Unknown platform\";\n            }\n        }\n    }\n\n    func name() {\n        match this {\n            case Linux(platform) => {\n                return platform.name();\n            }\n            case macOS(platform) => {\n                return platform.name();\n            }\n            case Unknown => {\n                return \"Unknown platform\";\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "lib/aria/test/test.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum TestResult {\n    case Pass,\n    case Fail(String)\n}\n\nextension TestResult {\n    func prettyprint() {\n        match this {\n            case Pass => { return \"passed\"; },\n            case Fail(e) => { return prettyprint(e); },\n        }\n    }\n}\n\nstruct ComparisonMismatch {\n    type func new(expected, actual, description) {\n        return alloc(This) {\n            .expected = expected,\n            .actual = actual,\n            .description = description\n        };\n    }\n\n    instance func prettyprint() {\n        return \"expected: {0} {1} {2}, but it was not\".format(this.actual, this.description, this.expected);\n    }\n}\n\nstruct OperationFailure {\n    type func new(operation, message) {\n        return alloc(This) {\n            .operation = operation,\n            .message = message\n        };\n    }\n\n    instance func prettyprint() {\n        return \"operation {0} expected to {1}\".format(this.operation, this.message);\n    }\n}\n\nmixin TestCase {\n    # this.test() is required, and expected to not throw any errors\n    # if test.setup() and test.teardown() are defined they will be called\n\n    # encourage tests to use setup/teardown for any non trivial construction\n    type func new() {\n        return alloc(This);\n    }\n\n    func run() {\n        if hasattr(this, \"setup\") {\n            try {\n                this.setup(); # setup cannot return error, but can throw\n            } catch e {\n                return TestResult::Fail(\"setup error: {0}\".format(e));\n            }\n        }\n\n        val ret = TestResult::Pass;\n\n        try {\n            this.test(); # test cannot return error, but can throw\n        } catch e {\n            ret = TestResult::Fail(\"test failure: {0}\".format(e));\n        }\n\n        if hasattr(this, \"teardown\") {\n            try {\n                this.teardown();\n            } catch e {\n                # ignore teardown errors for now\n                # should a teardown error cause a test to fail? probably not\n            }\n        }\n\n        return ret;\n    }\n\n    func assert_equal(expected, actual) {\n        if expected != actual {\n            throw ComparisonMismatch.new(expected, actual, \"equal to\");\n        }\n    }\n\n    func assert_not_equal(expected, actual) {\n        if expected == actual {\n            throw ComparisonMismatch.new(expected, actual, \"different from\");\n        }\n    }\n\n    func assert_throws(f) {\n        try {\n            f();\n            throw OperationFailure.new(prettyprint(f), \"throw but didn't\");\n        } catch e {\n            # this is expected\n        }\n    }\n}\n\nstruct TestSuite {\n    type func new(name) {\n        return alloc(This) {\n            .name = name,\n            .tests = []\n        };\n    }\n\n    instance func add_test(test) {\n        this.tests.append(test);\n        return this;\n    }\n\n    instance func run(silent=false) {\n        val num_fail = 0;\n        val num_pass = 0;\n        for test in this.tests {\n            val result = test.run();\n            if !silent {\n                println(\"{0}: {1}\".format(prettyprint(test), result.prettyprint()));\n            }\n            if result.is_Fail() {\n                num_fail += 1;\n            } else {\n                num_pass += 1;\n            }\n        }\n\n        if !silent {\n            println(\"{0} tests, {1} passed, {2} failed\".format(this.tests.len(), num_pass, num_fail));\n        }\n\n        return num_fail;\n    }\n}\n"
  },
  {
    "path": "lib/aria/utils/guard.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok,err from aria.core.result;\n\nfunc guard(x) = GuardImpl.new(x);\n\nstruct GuardImpl {\n    struct GuardError {\n        type func new(msg) = alloc(This) { .msg };\n        func prettyprint() = \"GuardError: {0}\".format(this.msg);\n    }\n\n    type func new(obj) = alloc(This) { .obj };\n\n    func _call_guard_exit() {\n        if hasattr(this.obj, \"guard_exit\") {\n            val arity_exit = arity(this.obj.guard_exit);\n            if arity_exit.can_call_with_argc(0) {\n                try {\n                    this.obj.guard_exit();\n                } catch _ {\n                    # ignore errors during guard_exit in this context\n                }\n            }\n        }\n    }\n\n    func do(f) {\n        val arity_f = arity(f);\n        if !arity_f.can_call_with_argc(1) {\n            return Result::Err(GuardError::new(\"guard function must take exactly one argument\"));\n        }\n        try {\n            val ret = f(this.obj);\n            this._call_guard_exit();\n            return ret?;\n        } catch e {\n            this._call_guard_exit();\n            throw e;\n        }\n    }\n}\n"
  },
  {
    "path": "lib-test/README.md",
    "content": "# lib/test\n\nlib/test contains modules to test Aria's import subsystem\n\nThese modules should not be used in production Aria programs as they are\nunstable and subject to change without notice"
  },
  {
    "path": "lib-test/all/source.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc something(x,y) {\n    return x + y - 1;\n}\n\nfunc something_else(x,y,z) {\n    return something(x,y) + z;\n}\n\nstruct SomeType {\n    type func new() {\n        return alloc(This) {\n            .x = 1,\n        };\n    }\n\n    instance func do_something() {\n        this.x = something(this.x, 3);\n        return this;\n    }\n}\n"
  },
  {
    "path": "lib-test/attributes/things.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x,y) {\n    return x + y;\n}\n\nstruct Bar {\n    type func new() {\n        return alloc(This);\n    }\n}\n\nenum A {\n    case X\n}\n\nmixin Something {\n    func answer() {\n        return 42;\n    }\n}\n"
  },
  {
    "path": "lib-test/base_module/nested_module/content.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func answer() {\n        return 42;\n    }\n}\n"
  },
  {
    "path": "lib-test/circular/one.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport circular.two;\n"
  },
  {
    "path": "lib-test/circular/two.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport circular.zero;\n"
  },
  {
    "path": "lib-test/circular/zero.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport circular.one;\n"
  },
  {
    "path": "lib-test/cool_widget/buzz.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Buzz {\n    func prettyprint() {\n        return \"Buzz is 25 years old\";\n    }\n}"
  },
  {
    "path": "lib-test/cool_widget/lib.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Buzz from widget.buzz;\nimport A from other_widget.a;\nimport B from other_widget.a;\n\nstruct Paco {\n    type func build_buzz() {\n        return alloc(Buzz);\n    }\n}\n\nstruct AWrapper {\n    type func new() {\n        return alloc(AWrapper) { .a = alloc(A) };\n    }\n    \n    func prettyprint() {\n        return this.a.prettyprint();\n    }\n}\n\nstruct BWrapper {\n    type func new() {\n        return alloc(BWrapper) { .b = B.new() };\n    }\n    \n    func prettyprint() {\n        return this.b.prettyprint();\n    }\n}"
  },
  {
    "path": "lib-test/cool_widget/widget.json",
    "content": "{}\n"
  },
  {
    "path": "lib-test/example/pair/Pair.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Pair {\n    type func new(x,y) {\n        return alloc(This){\n            .x = x,\n            .y = y,\n        };\n    }\n\n    func swap() {\n        return Pair.new(this.y, this.x);\n    }\n}\n\nextension Pair {\n    func max() {\n        if this.x > this.y {\n            return this.x;\n        } else {\n            return this.y;\n        }\n    }\n}\n"
  },
  {
    "path": "lib-test/example/two/things.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct One {\n    type func new(x) {\n        return alloc(This) {\n            .x = x + 1,\n        };\n    }\n\n    func double() {\n        return this.x + this.x;\n    }\n}\n\nstruct Two {\n    type func new(x) {\n        return alloc(This) {\n            .x = x - 1,\n        };\n    }\n\n    func half() {\n        return this.x / 2;\n    }\n}\n"
  },
  {
    "path": "lib-test/exported_var/source.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval foo = 123;\n\nfunc change_foo(x) {\n    foo = x;\n}\n\nfunc fetch_foo() {\n    return foo;\n}\n"
  },
  {
    "path": "lib-test/ext/string.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension String {\n    func test_method() {\n        return this.len() + 1;\n    }\n}\n"
  },
  {
    "path": "lib-test/extensible/base.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Base {\n    type func new(x,y) {\n        return alloc(This){\n            .x = x,\n            .y = y,\n        };\n    }\n\n    func swap() {\n        return Base.new(this.y, this.x);\n    }\n}\n"
  },
  {
    "path": "lib-test/extensible/ext.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport extensible.base;\nimport Base from extensible.base;\n\nextension extensible.base.Base {\n    func move(x,y) {\n        this.x = this.x + x;\n        this.y = this.y + y;\n        return this;\n    }\n\n    func one_right() {\n        return this.move(0,1);\n    }\n\n    func one_up() {\n        return this.move(1,0);\n    }\n\n    func prettyprint() {\n        return \"({0},{1})\".format(this.x, this.y);\n    }\n}\n"
  },
  {
    "path": "lib-test/multiple/module.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc one(x,y) {\n    return x + y;\n}\n\nfunc two(x,y) {\n    return x * y;\n}\n"
  },
  {
    "path": "lib-test/other_widget/a.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport InnerB from widget.mod.b;\n\nstruct A {\n    type func new() {\n        return alloc(A);\n    }\n    \n    func prettyprint() {\n        return \"A\";\n    }\n}\n\nstruct B {\n    type func new() {\n        return alloc(B) { .b = alloc(InnerB) };\n    }\n    \n    func prettyprint() {\n        return this.b.prettyprint();\n    }\n}"
  },
  {
    "path": "lib-test/other_widget/mod/b.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct InnerB {\n    func prettyprint() {\n         return \"InnerB\";\n    }\n}"
  },
  {
    "path": "lib-test/other_widget/widget.json",
    "content": "{}\n"
  },
  {
    "path": "lib-test/same_root/part1/file1.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport same_root.part1.file2;\n\nstruct Foo {\n    include same_root.part1.file2.Something\n\n    type func new() {\n        return alloc(This) {\n            .value = 123,\n        };\n    }\n}\n"
  },
  {
    "path": "lib-test/same_root/part1/file2.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Something {\n    func answer() {\n        return 42 + this.value;\n    }\n}\n"
  },
  {
    "path": "lib-test/same_root/part1/file3.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport same_root.part1.file2;\n\nstruct MeFirst {\n    include same_root.part1.file2.Something\n\n    type func new() {\n        return alloc(This) {\n            .value = 321,\n        };\n    }\n}\n"
  },
  {
    "path": "lib-test/test_things.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1;\n\nfunc foo(x,y) {\n    return x + y;\n}\n\nfunc bar(y) {\n    return x + y;\n}\n"
  },
  {
    "path": "lib-test/with_err/error.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct 123 {};\n"
  },
  {
    "path": "lsp/Cargo.toml",
    "content": "[package]\nname = \"lsp\"\nversion = \"0.1.0\"\nedition = \"2024\"\n\n[dependencies]\nlogos = \"0.16.1\"\nrowan = \"0.16.1\"\nline-index = \"0.1.2\"\ntower-lsp = \"0.20.0\"\ntokio = { version = \"1.49.0\", features = [\"full\"] }\nparking_lot = \"0.12\"\n\n[dev-dependencies]\npretty_assertions = \"1.4.1\"\n"
  },
  {
    "path": "lsp/src/document.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::collections::HashMap;\nuse std::sync::Arc;\n\nuse crate::parser::{self, Parse, SyntaxNode, SyntaxToken};\nuse line_index::{LineCol, LineIndex};\nuse rowan::{TextRange, TextSize};\n\n#[derive(Clone)]\npub struct DocumentState {\n    text: Arc<String>,\n    text_size: TextSize,\n    line_index: Arc<LineIndex>,\n    parse: Arc<Parse>,\n    defs: HashMap<String, Vec<DefEntry>>,\n}\n\nimpl DocumentState {\n    pub fn new(text: String) -> Self {\n        let line_index = LineIndex::new(&text);\n        let parse = parser::parse(&text);\n        let syntax = parse.syntax();\n        let defs = build_index(&syntax);\n        Self {\n            text_size: TextSize::of(&text),\n            text: Arc::new(text),\n            parse: Arc::new(parse),\n            line_index: Arc::new(line_index),\n            defs,\n        }\n    }\n\n    pub fn update_text(&mut self, text: String) {\n        self.text_size = TextSize::of(&text);\n        self.text = Arc::new(text);\n\n        self.line_index = Arc::new(LineIndex::new(&self.text));\n        let parse = parser::parse(&self.text);\n        let syntax = parse.syntax();\n\n        self.parse = Arc::new(parse);\n        self.defs = build_index(&syntax);\n    }\n\n    pub fn token_at_line_col(&self, line: u32, col: u32) -> Option<SyntaxToken> {\n        let line_col = line_index::LineCol { line, col };\n        let offset = self.line_index.offset(line_col)?;\n\n        use crate::lexer::SyntaxKind as K;\n\n        if offset > self.text_size {\n            return None;\n        }\n\n        match self.parse.syntax().token_at_offset(offset) {\n            rowan::TokenAtOffset::Single(tok) => Some(tok),\n            rowan::TokenAtOffset::Between(left, right) => {\n                // Prefer non-trivia if possible\n                let is_trivia =\n                    |t: &SyntaxToken| matches!(t.kind(), K::Whitespace | K::LineComment);\n                match (is_trivia(&left), is_trivia(&right)) {\n                    (false, false) => Some(left),\n                    (false, true) => Some(left),\n                    (true, false) => Some(right),\n                    (true, true) => Some(left),\n                }\n            }\n            rowan::TokenAtOffset::None => None,\n        }\n    }\n\n    pub fn line_col(&self, offset: rowan::TextSize) -> LineCol {\n        self.line_index.line_col(offset)\n    }\n\n    pub fn text(&self) -> String {\n        self.text.to_string()\n    }\n\n    pub fn offset_at_line_col(&self, line: u32, col: u32) -> Option<TextSize> {\n        let lc = line_index::LineCol { line, col };\n        self.line_index.offset(lc)\n    }\n\n    pub fn def(&self, line: u32, col: u32) -> Option<TextRange> {\n        let tok = self.token_at_line_col(line, col)?;\n        if tok.kind() == crate::lexer::SyntaxKind::Identifier {\n            let name = tok.text();\n            let at = tok.text_range().start();\n            let entries = self.defs.get(name)?;\n            let mut candidates: Vec<&DefEntry> = entries\n                .iter()\n                .filter(|e| e.scope_range.contains(at) && (e.hoisted || e.decl_start <= at))\n                .collect();\n\n            if candidates.is_empty() {\n                candidates = entries.iter().filter(|e| e.hoisted).collect();\n            }\n\n            candidates\n                .into_iter()\n                .min_by(|a, b| {\n                    use std::cmp::Ordering;\n                    let len_ord = a.scope_range.len().cmp(&b.scope_range.len());\n                    if len_ord != Ordering::Equal {\n                        return len_ord;\n                    }\n                    // Prefer later declaration start (descending)\n                    b.decl_start.cmp(&a.decl_start)\n                })\n                .map(|e| e.def_range)\n        } else {\n            None\n        }\n    }\n\n    pub fn parse_error_ranges(&self) -> Vec<(TextRange, String)> {\n        let mut out: Vec<(TextRange, String)> = Vec::new();\n\n        for err in self.parse.errors() {\n            let msg = format!(\"expected {:?}\", err.expected());\n            if let Some(pos) = err.pos() {\n                let start = TextSize::from(pos.start as u32);\n                let end = TextSize::from(pos.end as u32);\n                out.push((TextRange::new(start, end), msg));\n            } else {\n                let eof = self.text_size;\n                out.push((TextRange::new(eof, eof), msg));\n            }\n        }\n\n        out\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\nstruct DefEntry {\n    def_range: TextRange,\n    scope_range: TextRange,\n    decl_start: TextSize,\n    hoisted: bool,\n}\n\nfn build_index(root: &SyntaxNode) -> HashMap<String, Vec<DefEntry>> {\n    use crate::lexer::SyntaxKind as K;\n    let mut defs: HashMap<String, Vec<DefEntry>> = HashMap::new();\n\n    for node in root.descendants() {\n        match node.kind() {\n            K::StmtVal | K::Param | K::Func => {\n                if let Some(tok) = node\n                    .children_with_tokens()\n                    .filter_map(|e| e.into_token())\n                    .find(|t| t.kind() == K::Identifier)\n                {\n                    let name = tok.text().to_string();\n\n                    let mut scope_owner = node.parent();\n                    while let Some(parent) = scope_owner.clone() {\n                        match parent.kind() {\n                            K::Func | K::Block => break,\n                            _ => scope_owner = parent.parent(),\n                        }\n                    }\n\n                    let (scope_range, hoisted) = match scope_owner.as_ref() {\n                        Some(owner) => (owner.text_range(), false),\n                        None => (root.text_range(), true),\n                    };\n\n                    let entry = DefEntry {\n                        def_range: tok.text_range(),\n                        scope_range,\n                        decl_start: tok.text_range().start(),\n                        hoisted,\n                    };\n\n                    defs.entry(name).or_default().push(entry);\n                }\n            }\n            _ => {}\n        }\n    }\n\n    defs\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::lexer::SyntaxKind;\n\n    use super::*;\n\n    fn sample_text() -> String {\n        // 0: \"val x = 1;\"\n        // 1: \"func foo(a, b) {}\"\n        // 2: \"func bar() { val y = 2; }\"\n        \"val x = 1;\\nfunc foo(a, b) {}\\nfunc bar() { val y = 2; }\\n\".to_string()\n    }\n\n    #[test]\n    fn token_at_line_col_out_of_bounds_is_none() {\n        let doc = DocumentState::new(sample_text());\n        assert!(doc.token_at_line_col(0, 10_000).is_none());\n    }\n\n    #[test]\n    fn line_col_matches_token_start() {\n        let mut doc = DocumentState::new(sample_text());\n        let x_tok = doc.token_at_line_col(0, 4).expect(\"token x\");\n        assert_eq!(x_tok.text(), \"x\");\n        assert_eq!(x_tok.kind(), SyntaxKind::Identifier);\n\n        doc.update_text(sample_text() + \"\\nval x = 5;\");\n\n        let func_tok = doc.token_at_line_col(1, 0).expect(\"token func\");\n        assert_eq!(func_tok.text(), \"func\");\n        assert_eq!(func_tok.kind(), SyntaxKind::FuncKwd);\n    }\n\n    #[test]\n    fn parse_errors_include_expected_tokens() {\n        let text = \"val x\".to_string();\n        let doc = DocumentState::new(text);\n        let errs = doc.parse_error_ranges();\n        assert!(!errs.is_empty(), \"should report at least one parse error\");\n        assert!(\n            errs.iter()\n                .any(|(_, m)| m.contains(\"Assign\") || m.contains(\"Semicolon\")),\n            \"message should mention expected token like Assign or Semicolon: {:?}\",\n            errs\n        );\n    }\n}\n"
  },
  {
    "path": "lsp/src/lexer.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse logos::Logos;\n\n#[derive(Logos, Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord, Copy)]\n#[repr(u16)]\npub enum SyntaxKind {\n    #[token(\"assert\")]\n    AssertKwd,\n    #[token(\"break\")]\n    BreakKwd,\n    #[token(\"case\")]\n    CaseKwd,\n    #[token(\"catch\")]\n    CatchKwd,\n    #[token(\"continue\")]\n    ContinueKwd,\n    #[token(\"else\")]\n    ElseKwd,\n    #[token(\"elsif\")]\n    ElsifKwd,\n    #[token(\"enum\")]\n    EnumKwd,\n    #[token(\"extension\")]\n    ExtensionKwd,\n    #[token(\"flag\")]\n    FlagKwd,\n    #[token(\"for\")]\n    ForKwd,\n    #[token(\"from\")]\n    FromKwd,\n    #[token(\"func\")]\n    FuncKwd,\n    #[token(\"if\")]\n    IfKwd,\n    #[token(\"import\")]\n    ImportKwd,\n    #[token(\"in\")]\n    InKwd,\n    #[token(\"include\")]\n    IncludeKwd,\n    #[token(\"instance\")]\n    InstanceKwd,\n    #[token(\"isa\")]\n    IsaKwd,\n    #[token(\"match\")]\n    MatchKwd,\n    #[token(\"mixin\")]\n    MixinKwd,\n    #[token(\"operator\")]\n    OperatorKwd,\n    #[token(\"return\")]\n    ReturnKwd,\n    #[token(\"reverse\")]\n    ReverseKwd,\n    #[token(\"struct\")]\n    StructKwd,\n    #[token(\"throw\")]\n    ThrowKwd,\n    #[token(\"try\")]\n    TryKwd,\n    #[token(\"type\")]\n    TypeKwd,\n    #[token(\"val\")]\n    ValKwd,\n    #[token(\"while\")]\n    WhileKwd,\n    #[token(\"and\")]\n    AndKwd,\n\n    #[token(\"+\")]\n    Plus,\n    #[token(\"-\")]\n    Minus,\n    #[token(\"u-\")]\n    UnaryMinus,\n    #[token(\"*\")]\n    Star,\n    #[token(\"/\")]\n    Slash,\n    #[token(\"%\")]\n    Percent,\n    #[token(\"<<=\")]\n    LeftShiftAssign,\n    #[token(\">>=\")]\n    RightShiftAssign,\n    #[token(\"<<\")]\n    LeftShift,\n    #[token(\">>\")]\n    RightShift,\n    #[token(\"==\")]\n    Equal,\n    #[token(\"!=\")]\n    NotEqual,\n    #[token(\"<=\")]\n    LessEqual,\n    #[token(\">=\")]\n    GreaterEqual,\n    #[token(\"<\")]\n    Less,\n    #[token(\">\")]\n    Greater,\n    #[token(\"&&\")]\n    LogicalAnd,\n    #[token(\"||\")]\n    LogicalOr,\n    #[token(\"&\")]\n    BitwiseAnd,\n    #[token(\"|\")]\n    Pipe,\n    #[token(\"^\")]\n    BitwiseXor,\n    #[token(\"!\")]\n    Not,\n    #[token(\"=\")]\n    Assign,\n    #[token(\"+=\")]\n    PlusAssign,\n    #[token(\"-=\")]\n    MinusAssign,\n    #[token(\"*=\")]\n    StarAssign,\n    #[token(\"/=\")]\n    SlashAssign,\n    #[token(\"%=\")]\n    PercentAssign,\n    #[token(\"?\")]\n    Question,\n    #[token(\":\")]\n    Colon,\n    #[token(\"::\")]\n    DoubleColon,\n    #[token(\"=>\")]\n    Arrow,\n    #[token(\"...\")]\n    Ellipsis,\n\n    #[token(\"(\")]\n    LeftParen,\n    #[token(\")\")]\n    RightParen,\n    #[token(\"[\")]\n    LeftBracket,\n    #[token(\"]\")]\n    RightBracket,\n    #[token(\"{\")]\n    LeftBrace,\n    #[token(\"}\")]\n    RightBrace,\n    #[token(\",\")]\n    Comma,\n    #[token(\";\")]\n    Semicolon,\n    #[token(\".\")]\n    Dot,\n\n    #[token(\"true\")]\n    TrueKwd,\n    #[token(\"false\")]\n    FalseKwd,\n\n    #[regex(r\"0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*\")]\n    HexIntLiteral,\n\n    #[regex(r\"0o[0-7]+(_[0-7]+)*\")]\n    OctIntLiteral,\n\n    #[regex(r\"0b[01]+(_[01]+)*\")]\n    BinIntLiteral,\n\n    #[regex(r\"[0-9]+(_[0-9]+)*\")]\n    DecIntLiteral,\n\n    #[regex(r\"[0-9]+\\.[0-9]+([eE][+-]?[0-9]+)?f?\")]\n    FloatLiteral,\n\n    #[regex(r#\"\"([^\"\\\\]|\\\\.)*\"\"#)]\n    #[regex(r#\"'([^'\\\\]|\\\\.)*'\"#)]\n    StringLiteral,\n\n    #[regex(\n        r#\"[\\p{XID_Start}\\p{Emoji_Presentation}_$][\\p{XID_Continue}\\p{Emoji_Presentation}_$]*\"#,\n        priority = 1\n    )]\n    Identifier,\n\n    // trivia\n    #[regex(r\"[ \\t\\n\\f]+\")]\n    Whitespace,\n    #[regex(r\"#[^\\n]*\", allow_greedy = true)]\n    LineComment,\n\n    // Error token for unrecognized input\n    Error,\n\n    // compound types\n    File,\n    ErrorTree,\n    Func,\n    Lambda,\n    Block,\n    ParamList,\n    Param,\n    StmtVal,\n    StmtReturn,\n    StmtExpr,\n    StmtIf,\n    StmtFor,\n    StmtMatch,\n    StmtWhile,\n    StmtImport,\n    StmtAssert,\n    ExprName,\n    ExprCall,\n    ExprBinary,\n    ExprUnary,\n    ExprParen,\n    ExprLiteral,\n    ExprMember,\n    ExprIndex,\n    ExprTernary,\n    ExprAssign,\n    ExprType,\n    ExprNonNull,\n    ExprNullish,\n    Mixin,\n    MixinInclude,\n    MixinEntry,\n    Struct,\n    StructEntry,\n    Enum,\n    EnumCase,\n    EnumEntry,\n    Extension,\n    Operator,\n    Guard,\n    TryBlock,\n    MatchRule,\n    MatchPattern,\n    IdentList,\n    QualifiedIdent,\n    ImportPath,\n    ArgList,\n    ListLiteral,\n    ModuleFlag,\n    Eof,\n}\n\npub fn lex(s: &str) -> Vec<Result<(SyntaxKind, &str, logos::Span), LexError>> {\n    let mut lexer = SyntaxKind::lexer(s);\n    let mut tokens = Vec::new();\n\n    while let Some(token_result) = lexer.next() {\n        let slice = lexer.slice();\n        match token_result {\n            Ok(token) => tokens.push(Ok((token, slice, lexer.span()))),\n            Err(_) => {\n                let span = lexer.span();\n                tokens.push(Err(LexError {\n                    message: format!(\"Unexpected character(s): '{slice}'\"),\n                    span,\n                    text: slice.to_string(),\n                }));\n            }\n        }\n    }\n\n    tokens\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub struct LexError {\n    pub message: String,\n    pub span: std::ops::Range<usize>,\n    pub text: String,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn non_trivia_tokens(input: &str) -> Vec<SyntaxKind> {\n        use SyntaxKind::*;\n        lex(input)\n            .into_iter()\n            .filter_map(|r| r.ok())\n            .map(|(k, _, _)| k)\n            .filter(|k| !matches!(k, Whitespace | LineComment))\n            .collect()\n    }\n\n    #[test]\n    fn test_keywords() {\n        let tokens = non_trivia_tokens(\"func if else while\");\n        assert_eq!(tokens.len(), 4);\n        assert_eq!(tokens[0], SyntaxKind::FuncKwd);\n        assert_eq!(tokens[1], SyntaxKind::IfKwd);\n        assert_eq!(tokens[2], SyntaxKind::ElseKwd);\n        assert_eq!(tokens[3], SyntaxKind::WhileKwd);\n    }\n\n    #[test]\n    fn test_identifiers() {\n        let tokens = non_trivia_tokens(\"myVar _private $special\");\n        assert_eq!(tokens.len(), 3);\n        assert_eq!(tokens[0], SyntaxKind::Identifier);\n        assert_eq!(tokens[1], SyntaxKind::Identifier);\n        assert_eq!(tokens[2], SyntaxKind::Identifier);\n    }\n\n    #[test]\n    fn test_literals() {\n        let tokens = non_trivia_tokens(r#\"42 0x1A 0o77 0b101 3.14 \"hello\" 'world'\"#);\n        assert_eq!(tokens.len(), 7);\n        assert_eq!(tokens[0], SyntaxKind::DecIntLiteral);\n        assert_eq!(tokens[1], SyntaxKind::HexIntLiteral);\n        assert_eq!(tokens[2], SyntaxKind::OctIntLiteral);\n        assert_eq!(tokens[3], SyntaxKind::BinIntLiteral);\n        assert_eq!(tokens[4], SyntaxKind::FloatLiteral);\n        assert_eq!(tokens[5], SyntaxKind::StringLiteral);\n        assert_eq!(tokens[6], SyntaxKind::StringLiteral);\n    }\n\n    #[test]\n    fn test_operators() {\n        let tokens = non_trivia_tokens(\"+ - * / % == != <= >= << >> && ||\");\n        assert_eq!(tokens.len(), 13);\n        assert_eq!(tokens[0], SyntaxKind::Plus);\n        assert_eq!(tokens[1], SyntaxKind::Minus);\n        assert_eq!(tokens[2], SyntaxKind::Star);\n        assert_eq!(tokens[3], SyntaxKind::Slash);\n        assert_eq!(tokens[4], SyntaxKind::Percent);\n        assert_eq!(tokens[5], SyntaxKind::Equal);\n        assert_eq!(tokens[6], SyntaxKind::NotEqual);\n        assert_eq!(tokens[7], SyntaxKind::LessEqual);\n        assert_eq!(tokens[8], SyntaxKind::GreaterEqual);\n        assert_eq!(tokens[9], SyntaxKind::LeftShift);\n        assert_eq!(tokens[10], SyntaxKind::RightShift);\n        assert_eq!(tokens[11], SyntaxKind::LogicalAnd);\n        assert_eq!(tokens[12], SyntaxKind::LogicalOr);\n    }\n\n    #[test]\n    fn test_comments_and_whitespace() {\n        let tokens = non_trivia_tokens(\"func # this is a comment\\n  main\");\n        assert_eq!(tokens.len(), 2);\n        assert_eq!(tokens[0], SyntaxKind::FuncKwd);\n        assert_eq!(tokens[1], SyntaxKind::Identifier);\n    }\n\n    #[test]\n    fn test_complex_expression() {\n        let lexer = SyntaxKind::lexer(\"val x = func(a, b) { return a + b; }\");\n        let tokens: Vec<_> = lexer.collect();\n\n        assert!(!tokens.is_empty());\n        assert_eq!(tokens[0], Ok(SyntaxKind::ValKwd));\n    }\n\n    fn test_files_in_directory(dir: &str) {\n        use std::fs;\n        use std::path::Path;\n\n        println!(\"reading inside {dir}\");\n\n        let dir = Path::new(dir);\n\n        if !dir.exists() {\n            println!(\"Examples directory not found, skipping test\");\n            return;\n        }\n\n        let entries = fs::read_dir(dir).expect(\"Failed to read examples directory\");\n\n        for entry in entries {\n            let entry = entry.expect(\"Failed to read directory entry\");\n            let path = entry.path();\n\n            if path.extension().and_then(|s| s.to_str()) == Some(\"aria\") {\n                let filename = path.file_name().unwrap().to_str().unwrap();\n\n                let content =\n                    fs::read_to_string(&path).expect(&format!(\"Failed to read file: {}\", filename));\n\n                let tokens = lex(&content);\n\n                let errors: Vec<_> = tokens\n                    .iter()\n                    .filter_map(|token| token.as_ref().err())\n                    .collect();\n\n                if !errors.is_empty() {\n                    println!(\"\\n{} has lexer errors:\", filename);\n                    for error in &errors {\n                        println!(\n                            \"  {} at position {}..{}\",\n                            error.message, error.span.start, error.span.end\n                        );\n                    }\n                }\n\n                assert!(errors.is_empty());\n            }\n\n            if path.is_dir() {\n                test_files_in_directory(path.to_path_buf().to_str().unwrap());\n            }\n        }\n    }\n\n    #[test]\n    fn test_example_files_lex_without_errors() {\n        test_files_in_directory(\"../examples\");\n    }\n\n    #[test]\n    fn test_files_lex_without_errors() {\n        test_files_in_directory(\"../tests\");\n    }\n\n    #[test]\n    fn test_std_lib_lex_without_errors() {\n        test_files_in_directory(\"../lib\");\n    }\n\n    #[test]\n    fn test_std_lib_test_lex_without_errors() {\n        test_files_in_directory(\"../lib-test\");\n    }\n\n    #[test]\n    fn test_error_reporting() {\n        let tokens = lex(\"func @ invalid # comment\");\n\n        let errors: Vec<_> = tokens.iter().filter_map(|t| t.as_ref().err()).collect();\n\n        if !errors.is_empty() {\n            println!(\"Lexer errors found:\");\n            for error in &errors {\n                println!(\n                    \"  {} at position {}..{}\",\n                    error.message, error.span.start, error.span.end\n                );\n            }\n        }\n\n        let successful_tokens: Vec<_> = tokens.iter().filter_map(|t| t.as_ref().ok()).collect();\n        assert!(!successful_tokens.is_empty());\n        assert_eq!(successful_tokens[0].0, SyntaxKind::FuncKwd);\n    }\n\n    #[test]\n    fn test_star_number_separation() {\n        let tokens = lex(\"*2\");\n        let successful_tokens: Vec<_> = tokens.iter().filter_map(|t| t.as_ref().ok()).collect();\n\n        println!(\"Tokens for '*2': {:?}\", successful_tokens);\n\n        // Should be two tokens: Star and DecIntLiteral\n        assert_eq!(successful_tokens.len(), 2);\n        assert_eq!(successful_tokens[0].0, SyntaxKind::Star);\n        assert_eq!(successful_tokens[1].0, SyntaxKind::DecIntLiteral);\n        assert_eq!(successful_tokens[0].1, \"*\");\n        assert_eq!(successful_tokens[1].1, \"2\");\n    }\n\n    #[test]\n    fn test_operator_number_separation() {\n        // Test various operator-number combinations\n        let test_cases = vec![\n            (\n                \"*2\",\n                vec![(SyntaxKind::Star, \"*\"), (SyntaxKind::DecIntLiteral, \"2\")],\n            ),\n            (\n                \"+3\",\n                vec![(SyntaxKind::Plus, \"+\"), (SyntaxKind::DecIntLiteral, \"3\")],\n            ),\n            (\n                \"-4\",\n                vec![(SyntaxKind::Minus, \"-\"), (SyntaxKind::DecIntLiteral, \"4\")],\n            ),\n            (\n                \"/5\",\n                vec![(SyntaxKind::Slash, \"/\"), (SyntaxKind::DecIntLiteral, \"5\")],\n            ),\n            (\n                \"%6\",\n                vec![(SyntaxKind::Percent, \"%\"), (SyntaxKind::DecIntLiteral, \"6\")],\n            ),\n        ];\n\n        for (input, expected) in test_cases {\n            let tokens = lex(input);\n            let successful_tokens: Vec<_> = tokens.iter().filter_map(|t| t.as_ref().ok()).collect();\n\n            assert_eq!(\n                successful_tokens.len(),\n                expected.len(),\n                \"Failed for input: {}\",\n                input\n            );\n            for (i, (expected_kind, expected_text)) in expected.iter().enumerate() {\n                assert_eq!(\n                    successful_tokens[i].0, *expected_kind,\n                    \"Failed kind for input: {} at position {}\",\n                    input, i\n                );\n                assert_eq!(\n                    successful_tokens[i].1, *expected_text,\n                    \"Failed text for input: {} at position {}\",\n                    input, i\n                );\n            }\n        }\n    }\n\n    #[test]\n    fn test_emoji_identifiers() {\n        // Test emoji identifiers still work\n        let tokens = lex(\"😎 💯\");\n        let successful_tokens: Vec<_> = tokens\n            .into_iter()\n            .filter_map(|t| t.ok())\n            .filter(|(k, _, _)| !matches!(k, SyntaxKind::Whitespace | SyntaxKind::LineComment))\n            .collect();\n\n        assert_eq!(successful_tokens.len(), 2);\n        assert_eq!(successful_tokens[0].0, SyntaxKind::Identifier);\n        assert_eq!(successful_tokens[1].0, SyntaxKind::Identifier);\n        assert_eq!(successful_tokens[0].1, \"😎\");\n        assert_eq!(successful_tokens[1].1, \"💯\");\n    }\n}\n"
  },
  {
    "path": "lsp/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub mod document;\npub mod lexer;\npub mod parser;\n"
  },
  {
    "path": "lsp/src/main.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse line_index::{LineCol, LineIndex};\nuse lsp::document::DocumentState;\nuse rowan::TextRange;\nuse std::collections::HashMap;\nuse tokio::sync::mpsc::{UnboundedSender, unbounded_channel};\nuse tower_lsp::jsonrpc::Result;\nuse tower_lsp::lsp_types::*;\nuse tower_lsp::{Client, LanguageServer, LspService, Server};\n\n#[derive(Clone)]\nstruct Logger {\n    tx: UnboundedSender<String>,\n}\n\nimpl Logger {\n    fn new(client: Client) -> Self {\n        let (tx, mut rx) = unbounded_channel::<String>();\n        tokio::spawn(async move {\n            while let Some(msg) = rx.recv().await {\n                let _ = client.log_message(MessageType::INFO, msg).await;\n            }\n        });\n        Self { tx }\n    }\n\n    fn info(&self, msg: impl Into<String>) {\n        let _ = self.tx.send(msg.into());\n    }\n}\n\nstruct Backend {\n    logger: Logger,\n    client: Client,\n    documents: parking_lot::Mutex<HashMap<Url, DocumentState>>,\n}\n\nimpl Backend {\n    fn info(&self, msg: String) {\n        self.logger.info(msg);\n    }\n}\n\nfn to_lsp_position(doc: &DocumentState, offset: rowan::TextSize) -> Position {\n    let lc = doc.line_col(offset);\n    Position::new(lc.line, lc.col)\n}\n\nfn to_lsp_range(doc: &DocumentState, range: TextRange) -> Range {\n    Range::new(\n        to_lsp_position(doc, range.start()),\n        to_lsp_position(doc, range.end()),\n    )\n}\n\n#[tower_lsp::async_trait]\nimpl LanguageServer for Backend {\n    async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {\n        self.info(\"Initializing Aria LSP\".to_string());\n        Ok(InitializeResult {\n            server_info: None,\n            capabilities: ServerCapabilities {\n                text_document_sync: Some(TextDocumentSyncCapability::Kind(\n                    TextDocumentSyncKind::INCREMENTAL,\n                )),\n                definition_provider: Some(OneOf::Left(true)),\n                ..ServerCapabilities::default()\n            },\n        })\n    }\n\n    async fn initialized(&self, _: InitializedParams) {\n        self.info(\"Aria LSP initialized\".to_string());\n    }\n\n    async fn shutdown(&self) -> Result<()> {\n        Ok(())\n    }\n\n    async fn did_open(&self, params: DidOpenTextDocumentParams) {\n        let uri = params.text_document.uri;\n        let text = params.text_document.text;\n\n        self.info(format!(\"opened file {uri}\"));\n\n        let (diags, uri_clone) = {\n            let mut docs = self.documents.lock();\n            let doc = DocumentState::new(text);\n            let diags = {\n                let mut v = Vec::new();\n                for (range, msg) in doc.parse_error_ranges() {\n                    v.push(Diagnostic {\n                        range: to_lsp_range(&doc, range),\n                        severity: Some(DiagnosticSeverity::ERROR),\n                        code: None,\n                        code_description: None,\n                        source: Some(\"aria-parser\".into()),\n                        message: msg,\n                        related_information: None,\n                        tags: None,\n                        data: None,\n                    });\n                }\n                v\n            };\n            docs.insert(uri.clone(), doc);\n            (diags, uri.clone())\n        };\n        let _ = self\n            .client\n            .publish_diagnostics(uri_clone, diags, None)\n            .await;\n    }\n\n    async fn did_change(&self, params: DidChangeTextDocumentParams) {\n        let uri = params.text_document.uri;\n        let (diags_opt, uri_clone) = {\n            let mut docs = self.documents.lock();\n\n            if let Some(doc) = docs.get_mut(&uri) {\n                let mut text = doc.text();\n                let mut index = LineIndex::new(&text);\n\n                for change in params.content_changes {\n                    if let Some(range) = change.range {\n                        let Some(start_ts) = index.offset(LineCol {\n                            line: range.start.line,\n                            col: range.start.character,\n                        }) else {\n                            continue;\n                        };\n                        let Some(end_ts) = index.offset(LineCol {\n                            line: range.end.line,\n                            col: range.end.character,\n                        }) else {\n                            continue;\n                        };\n\n                        let start: usize = u32::from(start_ts) as usize;\n                        let end: usize = u32::from(end_ts) as usize;\n\n                        if start <= end && end <= text.len() {\n                            let mut new_text = String::with_capacity(\n                                text.len() - (end - start) + change.text.len(),\n                            );\n                            new_text.push_str(&text[..start]);\n                            new_text.push_str(&change.text);\n                            new_text.push_str(&text[end..]);\n                            text = new_text;\n                            index = LineIndex::new(&text);\n                        } else {\n                            self.info(format!(\n                                \"skipping invalid change range for {uri}: {range:?}\"\n                            ));\n                        }\n                    } else {\n                        // Full text replacement\n                        text = change.text;\n                        index = LineIndex::new(&text);\n                    }\n                }\n                doc.update_text(text);\n                let diags = {\n                    let mut v = Vec::new();\n                    for (range, msg) in doc.parse_error_ranges() {\n                        v.push(Diagnostic {\n                            range: to_lsp_range(doc, range),\n                            severity: Some(DiagnosticSeverity::ERROR),\n                            code: None,\n                            code_description: None,\n                            source: Some(\"aria-parser\".into()),\n                            message: msg,\n                            related_information: None,\n                            tags: None,\n                            data: None,\n                        });\n                    }\n                    v\n                };\n                (Some(diags), Some(uri.clone()))\n            } else {\n                (None, None)\n            }\n        };\n        if let (Some(diags), Some(uri2)) = (diags_opt, uri_clone) {\n            let _ = self.client.publish_diagnostics(uri2, diags, None).await;\n        }\n    }\n\n    async fn did_close(&self, params: DidCloseTextDocumentParams) {\n        let uri = params.text_document.uri;\n        let mut docs = self.documents.lock();\n        docs.remove(&uri);\n    }\n\n    async fn goto_definition(\n        &self,\n        params: GotoDefinitionParams,\n    ) -> Result<Option<GotoDefinitionResponse>> {\n        let uri = params.text_document_position_params.text_document.uri;\n        let position = params.text_document_position_params.position;\n\n        self.info(format!(\n            \"goto_definition {} {:?}\",\n            uri.clone(),\n            position.clone()\n        ));\n\n        let docs = self.documents.lock();\n        let Some(doc) = docs.get(&uri) else {\n            return Ok(None);\n        };\n\n        if let Some(def_range) = doc.def(position.line, position.character) {\n            let lsp_range = to_lsp_range(doc, def_range);\n            let loc = Location::new(uri.clone(), lsp_range);\n            self.info(format!(\"found a definition at {loc:?}\"));\n            return Ok(Some(GotoDefinitionResponse::Scalar(loc)));\n        }\n\n        self.info(\"no definitions found\".to_string());\n\n        Ok(None)\n    }\n}\n\n#[tokio::main]\nasync fn main() {\n    let stdin = tokio::io::stdin();\n    let stdout = tokio::io::stdout();\n\n    let (service, socket) = LspService::build(|client| {\n        let logger = Logger::new(client.clone());\n        Backend {\n            logger,\n            client: client.clone(),\n            documents: parking_lot::Mutex::new(HashMap::new()),\n        }\n    })\n    .finish();\n\n    Server::new(stdin, stdout, socket).serve(service).await;\n}\n"
  },
  {
    "path": "lsp/src/parser.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::lexer::{self, SyntaxKind};\nuse SyntaxKind::*;\nuse core::ops::Range;\nuse line_index::LineIndex;\nuse rowan::{GreenNode, GreenNodeBuilder, TextSize};\nuse std::cell::Cell;\n\nimpl From<SyntaxKind> for rowan::SyntaxKind {\n    fn from(kind: SyntaxKind) -> Self {\n        Self(kind as u16)\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub enum Lang {}\nimpl rowan::Language for Lang {\n    type Kind = SyntaxKind;\n    fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {\n        assert!(raw.0 <= Eof as u16);\n        unsafe { std::mem::transmute::<u16, SyntaxKind>(raw.0) }\n    }\n    fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {\n        kind.into()\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct ParseError {\n    expected: SyntaxKind,\n    pos: Option<Range<usize>>,\n}\n\npub struct Parse {\n    green_node: GreenNode,\n    errors: Vec<ParseError>,\n}\n\nimpl Parse {\n    pub fn syntax(&self) -> SyntaxNode {\n        SyntaxNode::new_root(self.green_node.clone())\n    }\n\n    pub fn errors(&self) -> &Vec<ParseError> {\n        &self.errors\n    }\n}\n\nimpl ParseError {\n    pub fn expected(&self) -> SyntaxKind {\n        self.expected\n    }\n    pub fn pos(&self) -> Option<Range<usize>> {\n        self.pos.clone()\n    }\n}\n\npub fn parse(text: &str) -> Parse {\n    #[derive(Debug)]\n    enum Event {\n        Open { kind: SyntaxKind },\n        Close,\n        Advance,\n    }\n\n    struct MarkOpened {\n        index: usize,\n    }\n\n    struct MarkClosed {\n        index: usize,\n    }\n\n    struct Parser<'a> {\n        tokens: Vec<(SyntaxKind, &'a str, logos::Span)>,\n        pos: usize,\n        fuel: Cell<u32>,\n        events: Vec<Event>,\n        errors: Vec<ParseError>,\n        line_index: LineIndex,\n    }\n\n    fn is_trivia(kind: SyntaxKind) -> bool {\n        matches!(kind, SyntaxKind::Whitespace | SyntaxKind::LineComment)\n    }\n\n    fn prefix_binding_power(op: SyntaxKind) -> Option<((), u8)> {\n        use SyntaxKind::*;\n        match op {\n            Not | Minus => Some(((), 23)),\n            _ => None,\n        }\n    }\n\n    fn is_expr_start(kind: SyntaxKind) -> bool {\n        use SyntaxKind::*;\n        matches!(\n            kind,\n            Identifier\n                | HexIntLiteral\n                | OctIntLiteral\n                | BinIntLiteral\n                | DecIntLiteral\n                | FloatLiteral\n                | StringLiteral\n                | TrueKwd\n                | FalseKwd\n                | LeftParen\n                | LeftBracket\n                | Pipe\n                | LogicalOr\n                | Not\n                | Minus\n        )\n    }\n\n    fn postfix_binding_power(op: SyntaxKind) -> Option<(u8, ())> {\n        use SyntaxKind::*;\n        match op {\n            LeftParen | LeftBracket | Dot | DoubleColon => Some((25, ())),\n            _ => None,\n        }\n    }\n\n    fn infix_binding_power(op: SyntaxKind) -> Option<(u8, u8)> {\n        use SyntaxKind::*;\n        match op {\n            // Assignment operators (right-associative, lowest precedence)\n            Assign | PlusAssign | MinusAssign | StarAssign | SlashAssign | PercentAssign\n            | LeftShiftAssign | RightShiftAssign => Some((2, 1)),\n\n            LogicalOr => Some((3, 4)),\n            LogicalAnd => Some((5, 6)),\n            BitwiseXor => Some((7, 8)),\n            BitwiseAnd => Some((9, 10)),\n            Pipe => Some((11, 12)),\n\n            Equal | NotEqual | IsaKwd => Some((13, 14)),\n\n            Less | LessEqual | Greater | GreaterEqual => Some((15, 16)),\n\n            LeftShift | RightShift => Some((17, 18)),\n\n            Plus | Minus => Some((19, 20)),\n\n            Star | Slash | Percent => Some((21, 22)),\n\n            _ => None,\n        }\n    }\n\n    impl Parser<'_> {\n        fn file(&mut self) {\n            let m: MarkOpened = self.open();\n            self.trivia();\n\n            while !self.eof() {\n                match self.nth(0) {\n                    ImportKwd => self.stmt_import(),\n                    FlagKwd => self.module_flag(),\n                    StructKwd => self.decl_struct_or_ext(Struct, StructKwd),\n                    MixinKwd => self.decl_mixin(),\n                    EnumKwd => self.decl_enum(),\n                    ExtensionKwd => self.decl_struct_or_ext(Extension, ExtensionKwd),\n                    FuncKwd => self.decl_func(),\n                    _ => self.stmt(),\n                }\n            }\n            self.trivia();\n            self.close(m, File);\n        }\n\n        fn mixin_include(&mut self) {\n            assert!(self.at(IncludeKwd));\n            let m = self.open();\n\n            self.expect(IncludeKwd);\n            let _ = self.expr();\n\n            self.close(m, MixinInclude);\n        }\n\n        fn decl_struct_or_ext(&mut self, kind: SyntaxKind, kwd: SyntaxKind) {\n            assert!(self.at(kwd));\n            let m = self.open();\n\n            self.expect(kwd);\n            if kwd == StructKwd {\n                self.qualified_ident();\n            } else {\n                let _ = self.expr();\n            }\n            self.expect(LeftBrace);\n\n            while !self.at(RightBrace) && !self.eof() {\n                self.entry(StructEntry);\n            }\n\n            self.expect(RightBrace);\n            self.close(m, kind);\n        }\n\n        fn entry(&mut self, kind: SyntaxKind) {\n            let m = self.open();\n            match self.nth(0) {\n                FuncKwd => self.decl_func(),\n                OperatorKwd | ReverseKwd => self.decl_operator(),\n                StructKwd => self.decl_struct_or_ext(Struct, StructKwd),\n                EnumKwd => self.decl_enum(),\n                IncludeKwd => self.mixin_include(),\n                TypeKwd | InstanceKwd => {\n                    if self.nth(1) == FuncKwd {\n                        self.decl_func();\n                    } else {\n                        self.decl_val();\n                    }\n                }\n                _ => self.advance_with_error(kind),\n            }\n            self.close(m, StructEntry);\n        }\n\n        fn decl_enum(&mut self) {\n            assert!(self.at(EnumKwd));\n            let m = self.open();\n\n            self.expect(EnumKwd);\n            self.qualified_ident();\n            self.expect(LeftBrace);\n\n            while !self.at(RightBrace) && !self.eof() {\n                match self.nth(0) {\n                    CaseKwd => self.enum_case(),\n                    _ => self.enum_entry(),\n                }\n\n                if self.at(Comma) {\n                    self.expect(Comma);\n                }\n            }\n\n            self.expect(RightBrace);\n            self.close(m, Enum);\n        }\n\n        fn module_flag(&mut self) {\n            assert!(self.at(FlagKwd));\n            let m = self.open();\n\n            self.expect(FlagKwd);\n            self.expect(Colon);\n            self.expect(Identifier);\n\n            if self.at(LeftParen) {\n                self.expect(LeftParen);\n                // Value must be a string literal per grammar\n                if self.at(StringLiteral) {\n                    self.expect(StringLiteral);\n                } else {\n                    // fall back to generic expr to recover if not a string\n                    let _ = self.expr();\n                }\n                self.expect(RightParen);\n            }\n\n            self.expect(Semicolon);\n            self.close(m, ModuleFlag);\n        }\n\n        fn enum_case(&mut self) {\n            assert!(self.at(CaseKwd));\n            let m = self.open();\n\n            self.expect(CaseKwd);\n            self.expect(Identifier);\n\n            if self.at(LeftParen) {\n                self.expect(LeftParen);\n                let _ = self.expr();\n                self.expect(RightParen);\n            }\n\n            self.close(m, EnumCase);\n        }\n\n        fn enum_entry(&mut self) {\n            let m = self.open();\n            self.entry(EnumEntry);\n            self.close(m, EnumEntry);\n        }\n\n        fn decl_mixin(&mut self) {\n            assert!(self.at(MixinKwd));\n            let m = self.open();\n\n            self.expect(MixinKwd);\n            self.qualified_ident();\n            self.expect(LeftBrace);\n\n            while !self.at(RightBrace) && !self.eof() {\n                self.entry(MixinEntry);\n            }\n\n            self.expect(RightBrace);\n            self.close(m, Mixin);\n        }\n\n        fn decl_operator(&mut self) {\n            let m = self.open();\n\n            if self.at(ReverseKwd) {\n                self.expect(ReverseKwd);\n            }\n\n            self.expect(OperatorKwd);\n\n            // Operator symbol - need to handle various operator tokens\n            match self.nth(0) {\n                Plus | Minus | UnaryMinus | Star | Slash | Percent | LeftShift | RightShift\n                | Equal | LessEqual | GreaterEqual | Less | Greater | BitwiseAnd | Pipe\n                | BitwiseXor => {\n                    self.advance();\n                }\n                LeftParen => {\n                    self.advance();\n                    self.expect(RightParen);\n                }\n                LeftBracket => {\n                    self.advance();\n                    self.expect(RightBracket);\n                    if self.at(Assign) {\n                        self.expect(Assign)\n                    }\n                }\n                _ => self.advance_with_error(Operator),\n            }\n\n            if self.at(LeftParen) {\n                self.param_list(LeftParen, RightParen);\n            }\n\n            self.func_body();\n\n            self.close(m, Operator);\n        }\n\n        fn decl_func(&mut self) {\n            let m = self.open();\n\n            self.parse_access_modifier();\n\n            self.expect(FuncKwd);\n            self.expect(Identifier);\n\n            if self.at(LeftParen) {\n                self.param_list(LeftParen, RightParen);\n            }\n\n            self.func_body();\n\n            self.close(m, Func);\n        }\n\n        fn func_body(&mut self) {\n            if self.at(LeftBrace) {\n                self.block();\n            } else if self.at(Assign) {\n                self.expect(Assign);\n                let _ = self.expr();\n                self.expect(Semicolon);\n            }\n        }\n\n        fn parse_access_modifier(&mut self) {\n            if self.at(TypeKwd) {\n                self.expect(TypeKwd);\n            }\n\n            if self.at(InstanceKwd) {\n                self.expect(InstanceKwd);\n            }\n        }\n\n        fn param_list(&mut self, left_delim: SyntaxKind, right_delim: SyntaxKind) {\n            self.assert_tok(left_delim);\n            let m = self.open();\n\n            self.expect(left_delim);\n            while !self.at(right_delim) && !self.eof() {\n                if self.at(Identifier) || self.at(Ellipsis) {\n                    self.param(self.nth(0), right_delim);\n                } else {\n                    break;\n                }\n            }\n            self.expect(right_delim);\n\n            self.close(m, ParamList);\n        }\n\n        fn param(&mut self, kind: SyntaxKind, right_delim: SyntaxKind) {\n            assert!(self.at(kind));\n            let m = self.open();\n\n            self.expect(kind);\n\n            if self.at(Colon) {\n                self.type_annotation();\n            }\n\n            // Support default value for optional parameters: name [: type] = expr\n            if self.at(Assign) {\n                self.expect(Assign);\n                let _ = self.expr();\n            }\n\n            if !self.at(right_delim) {\n                self.expect(Comma);\n            }\n\n            self.close(m, Param);\n        }\n\n        fn type_annotation(&mut self) {\n            self.assert_tok(Colon);\n            self.expect(Colon);\n            let m = self.open();\n            while self.at(Identifier) {\n                self.expect(Identifier);\n                if self.at(Dot) {\n                    self.expect(Dot);\n                }\n                if self.at(Pipe) {\n                    self.expect(Pipe);\n                }\n                if self.at(BitwiseAnd) {\n                    self.expect(BitwiseAnd);\n                }\n            }\n            self.close(m, ExprType);\n        }\n\n        fn block(&mut self) {\n            self.assert_tok(LeftBrace);\n            let m = self.open();\n\n            self.expect(LeftBrace);\n            while !self.at(RightBrace) && !self.eof() {\n                self.stmt();\n            }\n            self.expect(RightBrace);\n\n            self.close(m, Block);\n        }\n\n        fn stmt(&mut self) {\n            match self.nth(0) {\n                AssertKwd => self.stmt_kwd_with_expr(AssertKwd),\n                BreakKwd => self.stmt_single_token(BreakKwd),\n                ContinueKwd => self.stmt_single_token(ContinueKwd),\n                ValKwd => self.decl_val(),\n                IfKwd => self.stmt_if(),\n                MatchKwd => self.stmt_match(),\n                WhileKwd => self.stmt_while(),\n                ForKwd => self.stmt_for(),\n                ThrowKwd => self.stmt_kwd_with_expr(ThrowKwd),\n                ReturnKwd => self.stmt_return(),\n                LeftBrace => self.block(),\n                TryKwd => self.try_catch(),\n                StructKwd => self.decl_struct_or_ext(Struct, StructKwd),\n                EnumKwd => self.decl_enum(),\n                FuncKwd => self.decl_func(),\n                _ => self.stmt_expr(),\n            }\n        }\n\n        fn stmt_if(&mut self) {\n            assert!(self.at(IfKwd));\n            let m = self.open();\n\n            // if piece\n            self.expect(IfKwd);\n            let _ = self.expr();\n            self.block();\n\n            // elsif pieces\n            while self.at(ElsifKwd) {\n                self.expect(ElsifKwd);\n                let _ = self.expr();\n                self.block();\n            }\n\n            // optional else piece\n            if self.at(ElseKwd) {\n                self.expect(ElseKwd);\n                self.block();\n            }\n\n            self.close(m, StmtIf);\n        }\n\n        fn stmt_for(&mut self) {\n            assert!(self.at(ForKwd));\n            let m = self.open();\n\n            self.expect(ForKwd);\n            self.expect(Identifier);\n            self.expect(InKwd);\n            let _ = self.expr();\n            self.block();\n\n            // optional else piece\n            if self.at(ElseKwd) {\n                self.expect(ElseKwd);\n                self.block();\n            }\n\n            self.close(m, StmtFor);\n        }\n\n        fn stmt_match(&mut self) {\n            assert!(self.at(MatchKwd));\n            let m = self.open();\n\n            self.expect(MatchKwd);\n            let _ = self.expr();\n            self.expect(LeftBrace);\n\n            // Parse match rules\n            if !self.at(RightBrace) {\n                self.match_rule();\n\n                while (self.at(Comma) || !self.at(RightBrace)) && !self.eof() {\n                    if self.at(Comma) {\n                        self.expect(Comma);\n                    }\n                    if !self.at(RightBrace) {\n                        self.match_rule();\n                    }\n                }\n\n                if self.at(Comma) {\n                    self.expect(Comma);\n                }\n            }\n\n            self.expect(RightBrace);\n\n            // optional else piece\n            if self.at(ElseKwd) {\n                self.expect(ElseKwd);\n                self.block();\n            }\n\n            self.close(m, StmtMatch);\n        }\n\n        fn match_rule(&mut self) {\n            let m = self.open();\n\n            self.match_pattern();\n\n            // Handle \"and\" patterns\n            while self.at(AndKwd) {\n                self.expect(AndKwd);\n                self.match_pattern();\n            }\n\n            self.expect(Arrow); // \"=>\"\n            self.block();\n\n            self.close(m, MatchRule);\n        }\n\n        fn match_pattern(&mut self) {\n            let m = self.open();\n\n            match self.nth(0) {\n                CaseKwd => {\n                    self.expect(CaseKwd);\n                    self.expect(Identifier);\n                    if self.at(LeftParen) {\n                        self.expect(LeftParen);\n                        self.expect(Identifier);\n                        if self.at(Colon) {\n                            self.expect(Colon);\n                            let _ = self.expr();\n                        }\n                        self.expect(RightParen);\n                    }\n                }\n                Equal | NotEqual | IsaKwd => {\n                    self.advance(); // comparison operator\n                    let _ = self.expr();\n                }\n                Less | LessEqual | Greater | GreaterEqual => {\n                    self.advance(); // relational operator\n                    let _ = self.expr();\n                }\n                _ => self.advance_with_error(MatchPattern),\n            }\n\n            self.close(m, MatchPattern);\n        }\n\n        fn stmt_while(&mut self) {\n            assert!(self.at(WhileKwd));\n            let m = self.open();\n\n            self.expect(WhileKwd);\n            let _ = self.expr();\n            self.block();\n\n            // optional else piece\n            if self.at(ElseKwd) {\n                self.expect(ElseKwd);\n                self.block();\n            }\n\n            self.close(m, StmtWhile);\n        }\n\n        fn try_catch(&mut self) {\n            assert!(self.at(TryKwd));\n            let m = self.open();\n\n            self.expect(TryKwd);\n            self.block();\n            self.expect(CatchKwd);\n            self.expect(Identifier);\n            self.block();\n\n            self.close(m, TryBlock);\n        }\n\n        fn stmt_import(&mut self) {\n            assert!(self.at(ImportKwd));\n            let m = self.open();\n\n            self.expect(ImportKwd);\n\n            let mut is_from_import = false;\n            let mut temp_pos = self.pos;\n\n            while temp_pos < self.tokens.len()\n                && self.tokens[temp_pos].0 != FromKwd\n                && self.tokens[temp_pos].0 != Semicolon\n            {\n                temp_pos += 1;\n            }\n\n            if temp_pos < self.tokens.len() && self.tokens[temp_pos].0 == FromKwd {\n                is_from_import = true;\n            }\n\n            if is_from_import {\n                if self.at(Star) {\n                    self.expect(Star);\n                } else {\n                    self.ident_list();\n                }\n\n                self.expect(FromKwd);\n            }\n\n            self.import_path();\n            self.expect(Semicolon);\n\n            self.close(m, StmtImport);\n        }\n\n        fn decl_val(&mut self) {\n            let m = self.open();\n\n            self.parse_access_modifier();\n\n            self.expect(ValKwd);\n\n            loop {\n                self.expect(Identifier);\n\n                if self.at(Colon) {\n                    self.type_annotation();\n                }\n\n                self.expect(Assign);\n                let _ = self.expr();\n\n                if self.at(Comma) {\n                    self.expect(Comma);\n                } else {\n                    break;\n                }\n            }\n\n            self.expect(Semicolon);\n\n            self.close(m, StmtVal);\n        }\n\n        fn stmt_single_token(&mut self, kind: SyntaxKind) {\n            assert!(self.at(kind));\n            let m = self.open();\n\n            self.expect(kind);\n            self.expect(Semicolon);\n\n            self.close(m, StmtReturn);\n        }\n\n        fn stmt_return(&mut self) {\n            assert!(self.at(ReturnKwd));\n            let m = self.open();\n\n            self.expect(ReturnKwd);\n\n            if !self.at(Semicolon) {\n                let _ = self.expr();\n            }\n\n            self.expect(Semicolon);\n            self.close(m, StmtReturn);\n        }\n\n        fn stmt_kwd_with_expr(&mut self, kind: SyntaxKind) {\n            assert!(self.at(kind));\n            let m = self.open();\n\n            self.expect(kind);\n            let _ = self.expr();\n            self.expect(Semicolon);\n\n            self.close(m, StmtAssert);\n        }\n\n        fn init_list(&mut self) {\n            // Recognize an initializer block only when the brace starts with a field or index init\n            if self.at(LeftBrace) {\n                let ahead = self.nth(1);\n                if ahead != Dot && ahead != LeftBracket {\n                    return;\n                }\n            } else {\n                return;\n            }\n\n            self.assert_tok(LeftBrace);\n            self.expect(LeftBrace);\n\n            // Parse a comma-separated list of mixed field/index writes, optional trailing comma\n            while !self.at(RightBrace) && !self.eof() {\n                if self.at(Dot) {\n                    // Field write: .identifier [= expr]?\n                    self.expect(Dot);\n                    self.expect(Identifier);\n                    if self.at(Assign) {\n                        self.expect(Assign);\n                        let _ = self.expr();\n                    }\n                } else if self.at(LeftBracket) {\n                    // Index write: [expr_list?] = expr\n                    self.expr_list(LeftBracket, RightBracket);\n                    self.expect(Assign);\n                    let _ = self.expr();\n                } else {\n                    // Recovery: unexpected token inside init block\n                    self.report_error(RightBrace);\n                    break;\n                }\n\n                if self.at(Comma) {\n                    self.expect(Comma);\n                    // allow trailing comma; loop condition will exit on RightBrace\n                } else {\n                    // no more entries\n                    break;\n                }\n            }\n\n            self.expect(RightBrace);\n        }\n\n        fn ident_list(&mut self) {\n            let m = self.open();\n\n            self.expect(Identifier);\n            while self.at(Comma) {\n                self.expect(Comma);\n                if self.at(Identifier) {\n                    self.expect(Identifier);\n                }\n            }\n\n            self.close(m, IdentList);\n        }\n\n        fn qualified_ident(&mut self) {\n            let m = self.open();\n            self.expect(Identifier);\n            while self.at(Dot) {\n                self.expect(Dot);\n                self.expect(Identifier);\n            }\n            self.close(m, QualifiedIdent);\n        }\n\n        fn import_path(&mut self) {\n            let m = self.open();\n            self.qualified_ident();\n            self.close(m, ImportPath);\n        }\n\n        fn stmt_expr(&mut self) {\n            let m = self.open();\n\n            if !self.at(Semicolon) {\n                let _ = self.expr();\n\n                // Allow multiple comma-separated expressions in a single\n                // expression statement (e.g. multi-write patterns).\n                while self.at(Comma) {\n                    self.expect(Comma);\n\n                    // Allow a trailing comma before semicolon, but don't\n                    // try to parse another expression in that case.\n                    if self.at(Semicolon) {\n                        break;\n                    }\n\n                    let _ = self.expr();\n                }\n            }\n\n            self.expect(Semicolon);\n\n            self.close(m, StmtExpr);\n        }\n\n        fn expr(&mut self) -> MarkClosed {\n            if self.at(Pipe) || self.at(LogicalOr) {\n                self.decl_lambda()\n            } else {\n                self.expr_bp(0)\n            }\n        }\n\n        fn decl_lambda(&mut self) -> MarkClosed {\n            let m = self.open();\n\n            if self.at(LogicalOr) {\n                // Empty parameter list in the form of '||'\n                self.expect(LogicalOr);\n            } else {\n                // Standard parameter list in the form of '|x, y|'\n                self.param_list(Pipe, Pipe);\n            }\n            self.expect(Arrow);\n\n            if self.at(LeftBrace) {\n                self.block();\n            } else {\n                let _ = self.expr();\n            }\n\n            self.close(m, Lambda)\n        }\n\n        fn expr_bp(&mut self, min_bp: u8) -> MarkClosed {\n            let mut lhs = self.expr_primary();\n\n            loop {\n                let op = self.nth(0);\n\n                // Support initializer blocks as a postfix after any expression\n                // e.g. \"expr{ .field = value, [key] = value }\"\n                // Only consume if the brace actually starts an init block (next is '.' or '[')\n                if op == LeftBrace {\n                    let ahead = self.nth(1);\n                    if ahead == Dot || ahead == LeftBracket {\n                        self.init_list();\n                        continue;\n                    }\n                }\n\n                if let Some((l_bp, ())) = postfix_binding_power(op) {\n                    if l_bp < min_bp {\n                        break;\n                    }\n\n                    lhs = match op {\n                        LeftParen => {\n                            let m = self.open_before(lhs);\n                            self.arg_list();\n                            self.init_list();\n                            self.close(m, ExprCall)\n                        }\n                        LeftBracket => {\n                            let m = self.open_before(lhs);\n                            self.expr_list(LeftBracket, RightBracket);\n                            self.close(m, ExprIndex)\n                        }\n                        Dot => {\n                            let m = self.open_before(lhs);\n                            self.expect(Dot);\n                            self.expect(Identifier);\n                            self.close(m, ExprMember)\n                        }\n                        DoubleColon => {\n                            let m = self.open_before(lhs);\n                            self.expect(DoubleColon);\n                            self.expect(Identifier);\n                            if self.at(LeftParen) {\n                                self.expect(LeftParen);\n                                let _ = self.expr_bp(0);\n                                self.expect(RightParen);\n                            }\n                            self.close(m, ExprMember)\n                        }\n                        _ => break,\n                    };\n                    continue;\n                }\n\n                if op == Not {\n                    let l_bp = 25u8;\n                    if l_bp < min_bp {\n                        break;\n                    }\n                    let m = self.open_before(lhs);\n                    self.expect(Not);\n                    lhs = self.close(m, ExprNonNull);\n                    continue;\n                }\n\n                if op == Question && !self.is_ternary_question() {\n                    let l_bp = 25u8;\n                    if l_bp < min_bp {\n                        break;\n                    }\n                    let m = self.open_before(lhs);\n                    self.expect(Question);\n                    lhs = self.close(m, ExprNullish);\n                    continue;\n                }\n\n                if op == Question {\n                    let (l_bp, r_bp) = (1, 2);\n                    if l_bp < min_bp {\n                        break;\n                    }\n\n                    let m = self.open_before(lhs);\n                    self.expect(Question);\n                    let _ = self.expr_bp(r_bp);\n                    self.expect(Colon);\n                    let _ = self.expr_bp(r_bp);\n                    lhs = self.close(m, ExprTernary);\n                    continue;\n                }\n\n                if let Some((l_bp, r_bp)) = infix_binding_power(op) {\n                    if l_bp < min_bp {\n                        break;\n                    }\n\n                    let m = self.open_before(lhs);\n                    self.advance(); // consume operator\n                    let _ = self.expr_bp(r_bp);\n\n                    // Use ExprAssign for assignment operators, ExprBinary for others\n                    let node_kind = match op {\n                        Assign | PlusAssign | MinusAssign | StarAssign | SlashAssign\n                        | PercentAssign | LeftShiftAssign | RightShiftAssign => ExprAssign,\n                        _ => ExprBinary,\n                    };\n\n                    lhs = self.close(m, node_kind);\n                    continue;\n                }\n\n                break;\n            }\n\n            lhs\n        }\n\n        fn is_ternary_question(&self) -> bool {\n            let mut idx = self.pos + 1;\n            let mut first_kind = None;\n            while let Some(tok) = self.tokens.get(idx) {\n                if is_trivia(tok.0) {\n                    idx += 1;\n                    continue;\n                }\n                first_kind = Some(tok.0);\n                break;\n            }\n\n            let Some(first_kind) = first_kind else {\n                return false;\n            };\n            if !is_expr_start(first_kind) {\n                return false;\n            }\n\n            let mut paren_depth = 0i32;\n            let mut bracket_depth = 0i32;\n            let mut brace_depth = 0i32;\n            let mut scan_idx = idx;\n\n            while let Some(tok) = self.tokens.get(scan_idx) {\n                if is_trivia(tok.0) {\n                    scan_idx += 1;\n                    continue;\n                }\n\n                match tok.0 {\n                    LeftParen => paren_depth += 1,\n                    RightParen => {\n                        if paren_depth == 0 {\n                            return false;\n                        }\n                        paren_depth -= 1;\n                    }\n                    LeftBracket => bracket_depth += 1,\n                    RightBracket => {\n                        if bracket_depth == 0 {\n                            return false;\n                        }\n                        bracket_depth -= 1;\n                    }\n                    LeftBrace => brace_depth += 1,\n                    RightBrace => {\n                        if brace_depth == 0 {\n                            return false;\n                        }\n                        brace_depth -= 1;\n                    }\n                    Colon if paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 => {\n                        return true;\n                    }\n                    Comma | Semicolon\n                        if paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 =>\n                    {\n                        return false;\n                    }\n                    _ => {}\n                }\n                scan_idx += 1;\n            }\n\n            false\n        }\n\n        fn expr_primary(&mut self) -> MarkClosed {\n            let m = self.open();\n\n            match self.nth(0) {\n                HexIntLiteral | OctIntLiteral | BinIntLiteral | DecIntLiteral | FloatLiteral\n                | StringLiteral | TrueKwd | FalseKwd => {\n                    self.advance();\n                    self.close(m, ExprLiteral)\n                }\n\n                Identifier => {\n                    self.advance();\n                    self.init_list();\n                    self.close(m, ExprName)\n                }\n\n                LeftParen => {\n                    self.expect(LeftParen);\n                    let _ = self.expr_bp(0);\n                    self.expect(RightParen);\n                    self.close(m, ExprParen)\n                }\n\n                LeftBracket => {\n                    self.expr_list(LeftBracket, RightBracket);\n                    self.close(m, ListLiteral)\n                }\n\n                op if prefix_binding_power(op).is_some() => {\n                    let ((), r_bp) = prefix_binding_power(op).unwrap();\n                    self.advance();\n                    let _ = self.expr_bp(r_bp);\n                    self.close(m, ExprUnary)\n                }\n\n                _ => {\n                    if !self.eof() {\n                        self.advance();\n                    }\n                    self.close(m, ErrorTree)\n                }\n            }\n        }\n\n        fn expr_list(&mut self, left_delim: SyntaxKind, right_delim: SyntaxKind) {\n            self.expect(left_delim);\n\n            if self.at(right_delim) {\n                self.expect(right_delim);\n                return;\n            }\n\n            self.expr();\n\n            while self.at(Comma) && !self.eof() {\n                self.expect(Comma);\n                if !self.at(right_delim) {\n                    self.expr();\n                }\n            }\n            self.expect(right_delim);\n        }\n\n        fn arg_list(&mut self) {\n            assert!(self.at(LeftParen));\n            let m = self.open();\n            self.expr_list(LeftParen, RightParen);\n            self.close(m, ArgList);\n        }\n\n        fn open(&mut self) -> MarkOpened {\n            let mark = MarkOpened {\n                index: self.events.len(),\n            };\n            self.events.push(Event::Open { kind: ErrorTree });\n            mark\n        }\n\n        fn close(&mut self, m: MarkOpened, kind: SyntaxKind) -> MarkClosed {\n            self.events[m.index] = Event::Open { kind };\n            self.events.push(Event::Close);\n            MarkClosed { index: m.index }\n        }\n\n        fn open_before(&mut self, m: MarkClosed) -> MarkOpened {\n            let mark = MarkOpened { index: m.index };\n            // TODO: do something to avoid element shifting\n            self.events.insert(m.index, Event::Open { kind: ErrorTree });\n            mark\n        }\n\n        fn advance(&mut self) {\n            // Before consuming a significant token, emit any leading trivia\n            while let Some(tok) = self.tokens.get(self.pos) {\n                if is_trivia(tok.0) {\n                    self.events.push(Event::Advance);\n                    self.pos += 1;\n                } else {\n                    break;\n                }\n            }\n\n            assert!(!self.eof());\n            self.fuel.set(256);\n            self.events.push(Event::Advance);\n            self.pos += 1;\n        }\n\n        fn eof(&self) -> bool {\n            // true if there are no more non-trivia tokens\n            let mut idx = self.pos;\n            while let Some(tok) = self.tokens.get(idx) {\n                if is_trivia(tok.0) {\n                    idx += 1;\n                    continue;\n                }\n                return false;\n            }\n            true\n        }\n\n        fn nth(&self, lookahead: usize) -> SyntaxKind {\n            if self.fuel.get() == 0 {\n                panic!(\"parser is stuck\")\n            }\n            self.fuel.set(self.fuel.get() - 1);\n\n            let mut idx = self.pos;\n            let mut remaining = lookahead;\n            while let Some(tok) = self.tokens.get(idx) {\n                if is_trivia(tok.0) {\n                    idx += 1;\n                    continue;\n                }\n                if remaining == 0 {\n                    return tok.0;\n                }\n                remaining -= 1;\n                idx += 1;\n            }\n            Eof\n        }\n\n        fn nth_token(&self, lookahead: usize) -> Option<&(SyntaxKind, &str, logos::Span)> {\n            self.tokens.get(self.pos + lookahead)\n        }\n\n        fn at(&self, kind: SyntaxKind) -> bool {\n            self.nth(0) == kind || (kind == Identifier && self.is_keyword(self.nth(0)))\n        }\n\n        fn eat(&mut self, kind: SyntaxKind) -> bool {\n            if self.at(kind) {\n                self.advance();\n                true\n            } else {\n                false\n            }\n        }\n\n        fn is_keyword(&self, kind: SyntaxKind) -> bool {\n            matches!(\n                kind,\n                AssertKwd\n                    | BreakKwd\n                    | CaseKwd\n                    | CatchKwd\n                    | ContinueKwd\n                    | ElseKwd\n                    | ElsifKwd\n                    | EnumKwd\n                    | ExtensionKwd\n                    | FlagKwd\n                    | ForKwd\n                    | FromKwd\n                    | FuncKwd\n                    | IfKwd\n                    | ImportKwd\n                    | InKwd\n                    | IncludeKwd\n                    | InstanceKwd\n                    | IsaKwd\n                    | MatchKwd\n                    | MixinKwd\n                    | OperatorKwd\n                    | ReturnKwd\n                    | ReverseKwd\n                    | StructKwd\n                    | ThrowKwd\n                    | TryKwd\n                    | TypeKwd\n                    | ValKwd\n                    | WhileKwd\n                    | AndKwd\n                    | TrueKwd\n                    | FalseKwd\n            )\n        }\n\n        fn expect(&mut self, kind: SyntaxKind) {\n            if self.eat(kind) {\n                return;\n            }\n            self.report_error(kind);\n        }\n\n        fn advance_with_error(&mut self, token: SyntaxKind) {\n            let m = self.open();\n            self.report_error(token);\n            self.advance();\n            self.close(m, ErrorTree);\n        }\n\n        fn report_error(&mut self, expected: SyntaxKind) {\n            let pos = self.nth_token(0).map(|tok| tok.2.clone());\n\n            self.errors.push(ParseError { expected, pos });\n        }\n\n        fn trivia(&mut self) {\n            while let Some(tok) = self.tokens.get(self.pos) {\n                if is_trivia(tok.0) {\n                    self.events.push(Event::Advance);\n                    self.pos += 1;\n                } else {\n                    break;\n                }\n            }\n        }\n\n        fn assert_tok(&mut self, kind: SyntaxKind) {\n            assert!(\n                self.at(kind),\n                \"expected {:?} but found {:?} at {:?}\",\n                kind,\n                self.nth(0),\n                self.line_index.line_col(TextSize::from(self.pos as u32))\n            );\n        }\n\n        fn build_tree(self) -> Parse {\n            {\n                let mut opens = 0usize;\n                let mut closes = 0usize;\n                let mut advances = 0usize;\n                let mut depth = 0isize;\n                for (i, ev) in self.events.iter().enumerate() {\n                    match ev {\n                        Event::Open { .. } => {\n                            opens += 1;\n                            depth += 1;\n                        }\n                        Event::Close => {\n                            closes += 1;\n                            depth -= 1;\n                            assert!(\n                                depth >= 0,\n                                \"Unbalanced Close at event {i} (more closes than opens)\"\n                            );\n                        }\n                        Event::Advance => {\n                            advances += 1;\n                        }\n                    }\n                }\n                assert_eq!(\n                    opens, closes,\n                    \"Mismatched Open/Close count: opens={opens} closes={closes}\"\n                );\n                let total_tokens = self.tokens.len();\n                assert_eq!(\n                    advances, total_tokens,\n                    \"Advance count {advances} does not match tokens len {total_tokens}\"\n                );\n            }\n\n            // TODO: add a shared node cache\n            let mut builder = GreenNodeBuilder::new();\n            let mut tokens = self.tokens.into_iter();\n\n            for (idx, event) in self.events.into_iter().enumerate() {\n                let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| match event {\n                    Event::Open { kind } => {\n                        builder.start_node(kind.into());\n                    }\n                    Event::Close => {\n                        builder.finish_node();\n                    }\n                    Event::Advance => {\n                        let (token, slice, _) = tokens.next().unwrap();\n                        builder.token(token.into(), slice);\n                    }\n                }));\n                if res.is_err() {\n                    eprintln!(\"Rowan builder panic at event index {idx}\");\n                    std::panic::resume_unwind(res.err().unwrap());\n                }\n            }\n\n            assert!(tokens.next().is_none());\n\n            let res_finish =\n                std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| builder.finish()));\n            match res_finish {\n                Ok(gn) => Parse {\n                    green_node: gn,\n                    errors: self.errors,\n                },\n                Err(p) => {\n                    eprintln!(\"Rowan builder.finish() panic\");\n                    std::panic::resume_unwind(p)\n                }\n            }\n        }\n    }\n\n    let lex = lexer::lex(text);\n    let tokens = lex.into_iter().map(|res| res.unwrap()).collect();\n    let mut parser = Parser {\n        tokens,\n        pos: 0,\n        fuel: Cell::new(256),\n        events: Vec::new(),\n        errors: Vec::new(),\n        line_index: LineIndex::new(text),\n    };\n    parser.file();\n    parser.build_tree()\n}\n\npub type SyntaxNode = rowan::SyntaxNode<Lang>;\n\n#[allow(unused)]\npub type SyntaxToken = rowan::SyntaxToken<Lang>;\n\n#[allow(unused)]\npub type SyntaxElement = rowan::NodeOrToken<SyntaxNode, SyntaxToken>;\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use line_index::LineIndex;\n    use pretty_assertions::assert_eq;\n\n    fn tree_to_string(node: SyntaxNode) -> String {\n        let mut result = Vec::new();\n        let index = CompressedIndex::new(&node);\n        tree_to_string_impl(&node, 0, &index, &mut result);\n        result.join(\"\\n\")\n    }\n\n    // Build a mapping from original token ranges to compressed coordinates\n    // that exclude trivia.\n    struct CompressedIndex {\n        // (original_text_range, compressed_start, compressed_end)\n        entries: Vec<(rowan::TextRange, usize, usize)>,\n    }\n\n    impl CompressedIndex {\n        fn new(root: &SyntaxNode) -> Self {\n            use crate::lexer::SyntaxKind as K;\n            let mut entries = Vec::new();\n            let mut comp = 0usize;\n            for el in root.descendants_with_tokens() {\n                if let rowan::NodeOrToken::Token(tok) = el {\n                    if matches!(tok.kind(), K::Whitespace | K::LineComment) {\n                        continue;\n                    }\n                    let len = tok.text().len();\n                    let start = comp;\n                    let end = comp + len;\n                    entries.push((tok.text_range(), start, end));\n                    comp = end;\n                }\n            }\n            Self { entries }\n        }\n\n        fn token_range(&self, tok: &SyntaxToken) -> Option<(usize, usize)> {\n            let r = tok.text_range();\n            self.entries\n                .iter()\n                .find_map(|(rr, s, e)| if *rr == r { Some((*s, *e)) } else { None })\n        }\n\n        fn node_range(&self, node: &SyntaxNode) -> Option<(usize, usize)> {\n            use crate::lexer::SyntaxKind as K;\n            let mut first: Option<usize> = None;\n            let mut last: Option<usize> = None;\n            for el in node.descendants_with_tokens() {\n                if let rowan::NodeOrToken::Token(tok) = el {\n                    if matches!(tok.kind(), K::Whitespace | K::LineComment) {\n                        continue;\n                    }\n                    if let Some((s, e)) = self.token_range(&tok) {\n                        if first.is_none() {\n                            first = Some(s);\n                        }\n                        last = Some(e);\n                    }\n                }\n            }\n            match (first, last) {\n                (Some(s), Some(e)) => Some((s, e)),\n                _ => None,\n            }\n        }\n    }\n\n    fn tree_to_string_impl(\n        node: &SyntaxNode,\n        depth: usize,\n        index: &CompressedIndex,\n        result: &mut Vec<String>,\n    ) {\n        let indent = \"  \".repeat(depth);\n        if let Some((s, e)) = index.node_range(node) {\n            result.push(format!(\"{}{:?}@{}..{}\", indent, node.kind(), s, e));\n        } else {\n            // empty node\n            result.push(format!(\"{}{:?}@0..0\", indent, node.kind()));\n        }\n\n        for child in node.children_with_tokens() {\n            match child {\n                rowan::NodeOrToken::Node(child_node) => {\n                    tree_to_string_impl(&child_node, depth + 1, index, result);\n                }\n                rowan::NodeOrToken::Token(token) => {\n                    use crate::lexer::SyntaxKind as K;\n                    if matches!(token.kind(), K::Whitespace | K::LineComment) {\n                        continue;\n                    }\n                    let token_indent = \"  \".repeat(depth + 1);\n                    if let Some((s, e)) = index.token_range(&token) {\n                        result.push(format!(\n                            \"{}{:?}@{}..{} {:?}\",\n                            token_indent,\n                            token.kind(),\n                            s,\n                            e,\n                            token.text()\n                        ));\n                    }\n                }\n            }\n        }\n    }\n\n    fn expect_tree(input: &str, lines: &[&str]) {\n        let node = parse(input).syntax();\n        let tree_str = tree_to_string(node);\n        let expected = lines.join(\"\\n\");\n        assert_eq!(\n            expected, tree_str,\n            \"tree should be\\n{}\\nbut is\\n{}\",\n            expected, tree_str\n        );\n    }\n\n    #[test]\n    fn test_empty() {\n        expect_tree(\"\", &[\"File@0..0\"])\n    }\n\n    #[test]\n    fn test_empty_function() {\n        expect_tree(\n            \"func empty_func() {}\",\n            &[\n                \"File@0..18\",\n                \"  Func@0..18\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..14 \\\"empty_func\\\"\",\n                \"    ParamList@14..16\",\n                \"      LeftParen@14..15 \\\"(\\\"\",\n                \"      RightParen@15..16 \\\")\\\"\",\n                \"    Block@16..18\",\n                \"      LeftBrace@16..17 \\\"{\\\"\",\n                \"      RightBrace@17..18 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_param_list() {\n        expect_tree(\n            \"func empty_func(x, y) {}\",\n            &[\n                \"File@0..21\",\n                \"  Func@0..21\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..14 \\\"empty_func\\\"\",\n                \"    ParamList@14..19\",\n                \"      LeftParen@14..15 \\\"(\\\"\",\n                \"      Param@15..17\",\n                \"        Identifier@15..16 \\\"x\\\"\",\n                \"        Comma@16..17 \\\",\\\"\",\n                \"      Param@17..18\",\n                \"        Identifier@17..18 \\\"y\\\"\",\n                \"      RightParen@18..19 \\\")\\\"\",\n                \"    Block@19..21\",\n                \"      LeftBrace@19..20 \\\"{\\\"\",\n                \"      RightBrace@20..21 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_val() {\n        expect_tree(\n            \"func test() { val x = 5; }\",\n            &[\n                \"File@0..19\",\n                \"  Func@0..19\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..19\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..18\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprLiteral@16..17\",\n                \"          DecIntLiteral@16..17 \\\"5\\\"\",\n                \"        Semicolon@17..18 \\\";\\\"\",\n                \"      RightBrace@18..19 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_binary_expr() {\n        expect_tree(\n            \"func test() { val x = 1 + 2 * 3; }\",\n            &[\n                \"File@0..23\",\n                \"  Func@0..23\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..23\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..22\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprBinary@16..21\",\n                \"          ExprLiteral@16..17\",\n                \"            DecIntLiteral@16..17 \\\"1\\\"\",\n                \"          Plus@17..18 \\\"+\\\"\",\n                \"          ExprBinary@18..21\",\n                \"            ExprLiteral@18..19\",\n                \"              DecIntLiteral@18..19 \\\"2\\\"\",\n                \"            Star@19..20 \\\"*\\\"\",\n                \"            ExprLiteral@20..21\",\n                \"              DecIntLiteral@20..21 \\\"3\\\"\",\n                \"        Semicolon@21..22 \\\";\\\"\",\n                \"      RightBrace@22..23 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_list_literal_empty() {\n        expect_tree(\n            \"func test() { val x = []; }\",\n            &[\n                \"File@0..20\",\n                \"  Func@0..20\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..20\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..19\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ListLiteral@16..18\",\n                \"          LeftBracket@16..17 \\\"[\\\"\",\n                \"          RightBracket@17..18 \\\"]\\\"\",\n                \"        Semicolon@18..19 \\\";\\\"\",\n                \"      RightBrace@19..20 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_list_literal_with_elements() {\n        expect_tree(\n            \"func test() { val x = [1, 2, 3]; }\",\n            &[\n                \"File@0..25\",\n                \"  Func@0..25\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..25\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..24\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ListLiteral@16..23\",\n                \"          LeftBracket@16..17 \\\"[\\\"\",\n                \"          ExprLiteral@17..18\",\n                \"            DecIntLiteral@17..18 \\\"1\\\"\",\n                \"          Comma@18..19 \\\",\\\"\",\n                \"          ExprLiteral@19..20\",\n                \"            DecIntLiteral@19..20 \\\"2\\\"\",\n                \"          Comma@20..21 \\\",\\\"\",\n                \"          ExprLiteral@21..22\",\n                \"            DecIntLiteral@21..22 \\\"3\\\"\",\n                \"          RightBracket@22..23 \\\"]\\\"\",\n                \"        Semicolon@23..24 \\\";\\\"\",\n                \"      RightBrace@24..25 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_list_literal_nested() {\n        expect_tree(\n            \"func test() { val x = [[1, 2], [3]]; }\",\n            &[\n                \"File@0..29\",\n                \"  Func@0..29\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..29\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..28\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ListLiteral@16..27\",\n                \"          LeftBracket@16..17 \\\"[\\\"\",\n                \"          ListLiteral@17..22\",\n                \"            LeftBracket@17..18 \\\"[\\\"\",\n                \"            ExprLiteral@18..19\",\n                \"              DecIntLiteral@18..19 \\\"1\\\"\",\n                \"            Comma@19..20 \\\",\\\"\",\n                \"            ExprLiteral@20..21\",\n                \"              DecIntLiteral@20..21 \\\"2\\\"\",\n                \"            RightBracket@21..22 \\\"]\\\"\",\n                \"          Comma@22..23 \\\",\\\"\",\n                \"          ListLiteral@23..26\",\n                \"            LeftBracket@23..24 \\\"[\\\"\",\n                \"            ExprLiteral@24..25\",\n                \"              DecIntLiteral@24..25 \\\"3\\\"\",\n                \"            RightBracket@25..26 \\\"]\\\"\",\n                \"          RightBracket@26..27 \\\"]\\\"\",\n                \"        Semicolon@27..28 \\\";\\\"\",\n                \"      RightBrace@28..29 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_unary_expr() {\n        expect_tree(\n            \"func test() { val x = -5; }\",\n            &[\n                \"File@0..20\",\n                \"  Func@0..20\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..20\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..19\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprUnary@16..18\",\n                \"          Minus@16..17 \\\"-\\\"\",\n                \"          ExprLiteral@17..18\",\n                \"            DecIntLiteral@17..18 \\\"5\\\"\",\n                \"        Semicolon@18..19 \\\";\\\"\",\n                \"      RightBrace@19..20 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_member_access() {\n        expect_tree(\n            \"func test() { val x = obj.field; }\",\n            &[\n                \"File@0..27\",\n                \"  Func@0..27\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..27\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..26\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprMember@16..25\",\n                \"          ExprName@16..19\",\n                \"            Identifier@16..19 \\\"obj\\\"\",\n                \"          Dot@19..20 \\\".\\\"\",\n                \"          Identifier@20..25 \\\"field\\\"\",\n                \"        Semicolon@25..26 \\\";\\\"\",\n                \"      RightBrace@26..27 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_array_access() {\n        expect_tree(\n            \"func test() { val x = arr[0]; }\",\n            &[\n                \"File@0..24\",\n                \"  Func@0..24\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..24\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..23\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprIndex@16..22\",\n                \"          ExprName@16..19\",\n                \"            Identifier@16..19 \\\"arr\\\"\",\n                \"          LeftBracket@19..20 \\\"[\\\"\",\n                \"          ExprLiteral@20..21\",\n                \"            DecIntLiteral@20..21 \\\"0\\\"\",\n                \"          RightBracket@21..22 \\\"]\\\"\",\n                \"        Semicolon@22..23 \\\";\\\"\",\n                \"      RightBrace@23..24 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_function_call() {\n        expect_tree(\n            \"func test() { val x = foo(1, 2); }\",\n            &[\n                \"File@0..26\",\n                \"  Func@0..26\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..26\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..25\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprCall@16..24\",\n                \"          ExprName@16..19\",\n                \"            Identifier@16..19 \\\"foo\\\"\",\n                \"          ArgList@19..24\",\n                \"            LeftParen@19..20 \\\"(\\\"\",\n                \"            ExprLiteral@20..21\",\n                \"              DecIntLiteral@20..21 \\\"1\\\"\",\n                \"            Comma@21..22 \\\",\\\"\",\n                \"            ExprLiteral@22..23\",\n                \"              DecIntLiteral@22..23 \\\"2\\\"\",\n                \"            RightParen@23..24 \\\")\\\"\",\n                \"        Semicolon@24..25 \\\";\\\"\",\n                \"      RightBrace@25..26 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_chained_postfix() {\n        expect_tree(\n            \"func test() { val x = obj.method().field[0]; }\",\n            &[\n                \"File@0..39\",\n                \"  Func@0..39\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..39\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..38\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprIndex@16..37\",\n                \"          ExprMember@16..34\",\n                \"            ExprCall@16..28\",\n                \"              ExprMember@16..26\",\n                \"                ExprName@16..19\",\n                \"                  Identifier@16..19 \\\"obj\\\"\",\n                \"                Dot@19..20 \\\".\\\"\",\n                \"                Identifier@20..26 \\\"method\\\"\",\n                \"              ArgList@26..28\",\n                \"                LeftParen@26..27 \\\"(\\\"\",\n                \"                RightParen@27..28 \\\")\\\"\",\n                \"            Dot@28..29 \\\".\\\"\",\n                \"            Identifier@29..34 \\\"field\\\"\",\n                \"          LeftBracket@34..35 \\\"[\\\"\",\n                \"          ExprLiteral@35..36\",\n                \"            DecIntLiteral@35..36 \\\"0\\\"\",\n                \"          RightBracket@36..37 \\\"]\\\"\",\n                \"        Semicolon@37..38 \\\";\\\"\",\n                \"      RightBrace@38..39 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    fn test_files_in_directory_parse(dir: &str, dir_should_error: Vec<String>) {\n        use std::fs;\n        use std::path::Path;\n\n        let test_dir = Path::new(dir);\n\n        if !test_dir.exists() {\n            println!(\"Directory not found, skipping test: {}\", dir);\n            return;\n        }\n\n        let expect_err =\n            dir_should_error.contains(&test_dir.file_name().unwrap().to_str().unwrap().to_owned());\n\n        let entries = fs::read_dir(test_dir).expect(&format!(\"Failed to read directory: {}\", dir));\n\n        for entry in entries {\n            let entry = entry.expect(\"Failed to read directory entry\");\n            let path = entry.path();\n\n            if path.extension().and_then(|s| s.to_str()) == Some(\"aria\") {\n                let filename = path.file_name().unwrap().to_str().unwrap();\n\n                println!(\"Parsing {}\", filename);\n\n                let content =\n                    fs::read_to_string(&path).expect(&format!(\"Failed to read file: {}\", filename));\n\n                let parse_result = parse(&content);\n\n                if expect_err && parse_result.errors.is_empty() {\n                    println!(\"\\n{} should have parse errors but did not:\", filename);\n                    let line_index = LineIndex::new(&content);\n                    for error in &parse_result.errors {\n                        let line = line_index\n                            .line_col(error.pos.as_ref().unwrap().start.try_into().unwrap());\n                        println!(\"  {:?} at {:?}\", error, line);\n                    }\n\n                    println!(\"\\n\\n{}\", tree_to_string(parse_result.syntax()));\n\n                    panic!(\"Parse errors found in {}\", filename);\n                } else if !expect_err && !parse_result.errors.is_empty() {\n                    println!(\"\\n{} has parse errors:\", filename);\n                    let line_index = LineIndex::new(&content);\n                    for error in &parse_result.errors {\n                        let line = line_index\n                            .line_col(error.pos.as_ref().unwrap().start.try_into().unwrap());\n                        println!(\"  {:?} at {:?}\", error, line);\n                    }\n\n                    println!(\"\\n\\n{}\", tree_to_string(parse_result.syntax()));\n\n                    panic!(\"Parse errors found in {}\", filename);\n                }\n            }\n\n            if path.is_dir() {\n                test_files_in_directory_parse(\n                    path.to_path_buf().to_str().unwrap(),\n                    dir_should_error.clone(),\n                );\n            }\n        }\n    }\n\n    #[test]\n    fn test_assignment_basic() {\n        expect_tree(\n            \"func test() { x = 5; }\",\n            &[\n                \"File@0..16\",\n                \"  Func@0..16\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..16\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtExpr@11..15\",\n                \"        ExprAssign@11..14\",\n                \"          ExprName@11..12\",\n                \"            Identifier@11..12 \\\"x\\\"\",\n                \"          Assign@12..13 \\\"=\\\"\",\n                \"          ExprLiteral@13..14\",\n                \"            DecIntLiteral@13..14 \\\"5\\\"\",\n                \"        Semicolon@14..15 \\\";\\\"\",\n                \"      RightBrace@15..16 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_assignment_compound() {\n        expect_tree(\n            \"func test() { x += 5; }\",\n            &[\n                \"File@0..17\",\n                \"  Func@0..17\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..17\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtExpr@11..16\",\n                \"        ExprAssign@11..15\",\n                \"          ExprName@11..12\",\n                \"            Identifier@11..12 \\\"x\\\"\",\n                \"          PlusAssign@12..14 \\\"+=\\\"\",\n                \"          ExprLiteral@14..15\",\n                \"            DecIntLiteral@14..15 \\\"5\\\"\",\n                \"        Semicolon@15..16 \\\";\\\"\",\n                \"      RightBrace@16..17 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_assignment_all_compound_operators() {\n        expect_tree(\n            \"func test() { x -= 1; y *= 2; z /= 3; w %= 4; }\",\n            &[\n                \"File@0..32\",\n                \"  Func@0..32\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..32\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtExpr@11..16\",\n                \"        ExprAssign@11..15\",\n                \"          ExprName@11..12\",\n                \"            Identifier@11..12 \\\"x\\\"\",\n                \"          MinusAssign@12..14 \\\"-=\\\"\",\n                \"          ExprLiteral@14..15\",\n                \"            DecIntLiteral@14..15 \\\"1\\\"\",\n                \"        Semicolon@15..16 \\\";\\\"\",\n                \"      StmtExpr@16..21\",\n                \"        ExprAssign@16..20\",\n                \"          ExprName@16..17\",\n                \"            Identifier@16..17 \\\"y\\\"\",\n                \"          StarAssign@17..19 \\\"*=\\\"\",\n                \"          ExprLiteral@19..20\",\n                \"            DecIntLiteral@19..20 \\\"2\\\"\",\n                \"        Semicolon@20..21 \\\";\\\"\",\n                \"      StmtExpr@21..26\",\n                \"        ExprAssign@21..25\",\n                \"          ExprName@21..22\",\n                \"            Identifier@21..22 \\\"z\\\"\",\n                \"          SlashAssign@22..24 \\\"/=\\\"\",\n                \"          ExprLiteral@24..25\",\n                \"            DecIntLiteral@24..25 \\\"3\\\"\",\n                \"        Semicolon@25..26 \\\";\\\"\",\n                \"      StmtExpr@26..31\",\n                \"        ExprAssign@26..30\",\n                \"          ExprName@26..27\",\n                \"            Identifier@26..27 \\\"w\\\"\",\n                \"          PercentAssign@27..29 \\\"%=\\\"\",\n                \"          ExprLiteral@29..30\",\n                \"            DecIntLiteral@29..30 \\\"4\\\"\",\n                \"        Semicolon@30..31 \\\";\\\"\",\n                \"      RightBrace@31..32 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_assignment_precedence() {\n        expect_tree(\n            \"func test() { x = y + z; }\",\n            &[\n                \"File@0..18\",\n                \"  Func@0..18\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..18\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtExpr@11..17\",\n                \"        ExprAssign@11..16\",\n                \"          ExprName@11..12\",\n                \"            Identifier@11..12 \\\"x\\\"\",\n                \"          Assign@12..13 \\\"=\\\"\",\n                \"          ExprBinary@13..16\",\n                \"            ExprName@13..14\",\n                \"              Identifier@13..14 \\\"y\\\"\",\n                \"            Plus@14..15 \\\"+\\\"\",\n                \"            ExprName@15..16\",\n                \"              Identifier@15..16 \\\"z\\\"\",\n                \"        Semicolon@16..17 \\\";\\\"\",\n                \"      RightBrace@17..18 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_assignment_right_associative() {\n        expect_tree(\n            \"func test() { x = y = z; }\",\n            &[\n                \"File@0..18\",\n                \"  Func@0..18\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..18\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtExpr@11..17\",\n                \"        ExprAssign@11..16\",\n                \"          ExprName@11..12\",\n                \"            Identifier@11..12 \\\"x\\\"\",\n                \"          Assign@12..13 \\\"=\\\"\",\n                \"          ExprAssign@13..16\",\n                \"            ExprName@13..14\",\n                \"              Identifier@13..14 \\\"y\\\"\",\n                \"            Assign@14..15 \\\"=\\\"\",\n                \"            ExprName@15..16\",\n                \"              Identifier@15..16 \\\"z\\\"\",\n                \"        Semicolon@16..17 \\\";\\\"\",\n                \"      RightBrace@17..18 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_simple_binary_expr() {\n        expect_tree(\n            \"func test() { val x = y-1; }\",\n            &[\n                \"File@0..21\",\n                \"  Func@0..21\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..21\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtVal@11..20\",\n                \"        ValKwd@11..14 \\\"val\\\"\",\n                \"        Identifier@14..15 \\\"x\\\"\",\n                \"        Assign@15..16 \\\"=\\\"\",\n                \"        ExprBinary@16..19\",\n                \"          ExprName@16..17\",\n                \"            Identifier@16..17 \\\"y\\\"\",\n                \"          Minus@17..18 \\\"-\\\"\",\n                \"          ExprLiteral@18..19\",\n                \"            DecIntLiteral@18..19 \\\"1\\\"\",\n                \"        Semicolon@19..20 \\\";\\\"\",\n                \"      RightBrace@20..21 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_assert_statement() {\n        expect_tree(\n            \"func test() { assert x > 0; }\",\n            &[\n                \"File@0..22\",\n                \"  Func@0..22\",\n                \"    FuncKwd@0..4 \\\"func\\\"\",\n                \"    Identifier@4..8 \\\"test\\\"\",\n                \"    ParamList@8..10\",\n                \"      LeftParen@8..9 \\\"(\\\"\",\n                \"      RightParen@9..10 \\\")\\\"\",\n                \"    Block@10..22\",\n                \"      LeftBrace@10..11 \\\"{\\\"\",\n                \"      StmtAssert@11..21\",\n                \"        AssertKwd@11..17 \\\"assert\\\"\",\n                \"        ExprBinary@17..20\",\n                \"          ExprName@17..18\",\n                \"            Identifier@17..18 \\\"x\\\"\",\n                \"          Greater@18..19 \\\">\\\"\",\n                \"          ExprLiteral@19..20\",\n                \"            DecIntLiteral@19..20 \\\"0\\\"\",\n                \"        Semicolon@20..21 \\\";\\\"\",\n                \"      RightBrace@21..22 \\\"}\\\"\",\n            ],\n        )\n    }\n\n    #[test]\n    fn test_example_files_parse_without_errors() {\n        test_files_in_directory_parse(\"../examples\", vec![]);\n    }\n\n    #[test]\n    fn test_files_parse_without_errors() {\n        test_files_in_directory_parse(\"../tests\", vec![]);\n    }\n\n    #[test]\n    fn test_std_lib_files_parse_without_errors() {\n        test_files_in_directory_parse(\"../lib\", vec![]);\n    }\n\n    #[test]\n    fn test_std_lib_test_files_parse_without_errors() {\n        test_files_in_directory_parse(\"../lib-test\", vec![\"with_err\".to_string()]);\n    }\n}\n"
  },
  {
    "path": "microbenchmarks/attribute_read.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nfunc foo(_) {}\n\nstruct ListWrite : Microbenchmark {\n    func prepare() {\n        val b = Box();\n        b.value0 = 0;\n        b.value1 = 1;\n        b.value2 = 2;\n        b.value3 = 3;\n        b.value4 = 4;\n        b.value5 = 5;\n        b.value6 = 6;\n        b.value7 = 7;\n        b.value8 = 8;\n        b.value9 = 9;\n        b.value10 = 10;\n        b.value11 = 11;\n        b.value12 = 12;\n        b.value13 = 13;\n        b.value14 = 14;\n        b.value15 = 15;\n        b.value16 = 16;\n        b.value17 = 17;\n        b.value18 = 18;\n        b.value19 = 19;\n        b.value20 = 20;\n        b.value21 = 21;\n        b.value22 = 22;\n        b.value23 = 23;\n        b.value24 = 24;\n        b.value25 = 25;\n        b.value26 = 26;\n        b.value27 = 27;\n        b.value28 = 28;\n        b.value29 = 29;\n        b.value30 = 30;\n        b.value31 = 31;\n        b.value32 = 32;\n        b.value33 = 33;\n        b.value34 = 34;\n        b.value35 = 35;\n        b.value36 = 36;\n        b.value37 = 37;\n        b.value38 = 38;\n        b.value39 = 39;\n        b.value40 = 40;\n        b.value41 = 41;\n        b.value42 = 42;\n        b.value43 = 43;\n        b.value44 = 44;\n        b.value45 = 45;\n        b.value46 = 46;\n        b.value47 = 47;\n        b.value48 = 48;\n        b.value49 = 49;\n        b.value50 = 50;\n        b.value51 = 51;\n        b.value52 = 52;\n        b.value53 = 53;\n        b.value54 = 54;\n        b.value55 = 55;\n        b.value56 = 56;\n        b.value57 = 57;\n        b.value58 = 58;\n        b.value59 = 59;\n        b.value60 = 60;\n        b.value61 = 61;\n        b.value62 = 62;\n        b.value63 = 63;\n        b.value64 = 64;\n        b.value65 = 65;\n        b.value66 = 66;\n        b.value67 = 67;\n        b.value68 = 68;\n        b.value69 = 69;\n        b.value70 = 70;\n        b.value71 = 71;\n        b.value72 = 72;\n        b.value73 = 73;\n        b.value74 = 74;\n        b.value75 = 75;\n        b.value76 = 76;\n        b.value77 = 77;\n        b.value78 = 78;\n        b.value79 = 79;\n        b.value80 = 80;\n        b.value81 = 81;\n        b.value82 = 82;\n        b.value83 = 83;\n        b.value84 = 84;\n        b.value85 = 85;\n        b.value86 = 86;\n        b.value87 = 87;\n        b.value88 = 88;\n        b.value89 = 89;\n        b.value90 = 90;\n        b.value91 = 91;\n        b.value92 = 92;\n        b.value93 = 93;\n        b.value94 = 94;\n        b.value95 = 95;\n        b.value96 = 96;\n        b.value97 = 97;\n        b.value98 = 98;\n        b.value99 = 99;\n        b.value100 = 100;\n        b.value101 = 101;\n        b.value102 = 102;\n        b.value103 = 103;\n        b.value104 = 104;\n        b.value105 = 105;\n        b.value106 = 106;\n        b.value107 = 107;\n        b.value108 = 108;\n        b.value109 = 109;\n        b.value110 = 110;\n        b.value111 = 111;\n        b.value112 = 112;\n        b.value113 = 113;\n        b.value114 = 114;\n        b.value115 = 115;\n        b.value116 = 116;\n        b.value117 = 117;\n        b.value118 = 118;\n        b.value119 = 119;\n        b.value120 = 120;\n        b.value121 = 121;\n        b.value122 = 122;\n        b.value123 = 123;\n        b.value124 = 124;\n        b.value125 = 125;\n        b.value126 = 126;\n        b.value127 = 127;\n        b.value128 = 128;\n        b.value129 = 129;\n        b.value130 = 130;\n        b.value131 = 131;\n        b.value132 = 132;\n        b.value133 = 133;\n        b.value134 = 134;\n        b.value135 = 135;\n        b.value136 = 136;\n        b.value137 = 137;\n        b.value138 = 138;\n        b.value139 = 139;\n        b.value140 = 140;\n        b.value141 = 141;\n        b.value142 = 142;\n        b.value143 = 143;\n        b.value144 = 144;\n        b.value145 = 145;\n        b.value146 = 146;\n        b.value147 = 147;\n        b.value148 = 148;\n        b.value149 = 149;\n        b.value150 = 150;\n        b.value151 = 151;\n        b.value152 = 152;\n        b.value153 = 153;\n        b.value154 = 154;\n        b.value155 = 155;\n        b.value156 = 156;\n        b.value157 = 157;\n        b.value158 = 158;\n        b.value159 = 159;\n        b.value160 = 160;\n        b.value161 = 161;\n        b.value162 = 162;\n        b.value163 = 163;\n        b.value164 = 164;\n        b.value165 = 165;\n        b.value166 = 166;\n        b.value167 = 167;\n        b.value168 = 168;\n        b.value169 = 169;\n        b.value170 = 170;\n        b.value171 = 171;\n        b.value172 = 172;\n        b.value173 = 173;\n        b.value174 = 174;\n        b.value175 = 175;\n        b.value176 = 176;\n        b.value177 = 177;\n        b.value178 = 178;\n        b.value179 = 179;\n        b.value180 = 180;\n        b.value181 = 181;\n        b.value182 = 182;\n        b.value183 = 183;\n        b.value184 = 184;\n        b.value185 = 185;\n        b.value186 = 186;\n        b.value187 = 187;\n        b.value188 = 188;\n        b.value189 = 189;\n        b.value190 = 190;\n        b.value191 = 191;\n        b.value192 = 192;\n        b.value193 = 193;\n        b.value194 = 194;\n        b.value195 = 195;\n        b.value196 = 196;\n        b.value197 = 197;\n        b.value198 = 198;\n        b.value199 = 199;\n        b.value200 = 200;\n        b.value201 = 201;\n        b.value202 = 202;\n        b.value203 = 203;\n        b.value204 = 204;\n        b.value205 = 205;\n        b.value206 = 206;\n        b.value207 = 207;\n        b.value208 = 208;\n        b.value209 = 209;\n        b.value210 = 210;\n        b.value211 = 211;\n        b.value212 = 212;\n        b.value213 = 213;\n        b.value214 = 214;\n        b.value215 = 215;\n        b.value216 = 216;\n        b.value217 = 217;\n        b.value218 = 218;\n        b.value219 = 219;\n        b.value220 = 220;\n        b.value221 = 221;\n        b.value222 = 222;\n        b.value223 = 223;\n        b.value224 = 224;\n        b.value225 = 225;\n        b.value226 = 226;\n        b.value227 = 227;\n        b.value228 = 228;\n        b.value229 = 229;\n        b.value230 = 230;\n        b.value231 = 231;\n        b.value232 = 232;\n        b.value233 = 233;\n        b.value234 = 234;\n        b.value235 = 235;\n        b.value236 = 236;\n        b.value237 = 237;\n        b.value238 = 238;\n        b.value239 = 239;\n        b.value240 = 240;\n        b.value241 = 241;\n        b.value242 = 242;\n        b.value243 = 243;\n        b.value244 = 244;\n        b.value245 = 245;\n        b.value246 = 246;\n        b.value247 = 247;\n        b.value248 = 248;\n        b.value249 = 249;\n        b.value250 = 250;\n        b.value251 = 251;\n        b.value252 = 252;\n        b.value253 = 253;\n        b.value254 = 254;\n        b.value255 = 255;\n        b.value256 = 256;\n        b.value257 = 257;\n        b.value258 = 258;\n        b.value259 = 259;\n        b.value260 = 260;\n        b.value261 = 261;\n        b.value262 = 262;\n        b.value263 = 263;\n        b.value264 = 264;\n        b.value265 = 265;\n        b.value266 = 266;\n        b.value267 = 267;\n        b.value268 = 268;\n        b.value269 = 269;\n        b.value270 = 270;\n        b.value271 = 271;\n        b.value272 = 272;\n        b.value273 = 273;\n        b.value274 = 274;\n        b.value275 = 275;\n        b.value276 = 276;\n        b.value277 = 277;\n        b.value278 = 278;\n        b.value279 = 279;\n        b.value280 = 280;\n        b.value281 = 281;\n        b.value282 = 282;\n        b.value283 = 283;\n        b.value284 = 284;\n        b.value285 = 285;\n        b.value286 = 286;\n        b.value287 = 287;\n        b.value288 = 288;\n        b.value289 = 289;\n        b.value290 = 290;\n        b.value291 = 291;\n        b.value292 = 292;\n        b.value293 = 293;\n        b.value294 = 294;\n        b.value295 = 295;\n        b.value296 = 296;\n        b.value297 = 297;\n        b.value298 = 298;\n        b.value299 = 299;\n        b.value300 = 300;\n        b.value301 = 301;\n        b.value302 = 302;\n        b.value303 = 303;\n        b.value304 = 304;\n        b.value305 = 305;\n        b.value306 = 306;\n        b.value307 = 307;\n        b.value308 = 308;\n        b.value309 = 309;\n        b.value310 = 310;\n        b.value311 = 311;\n        b.value312 = 312;\n        b.value313 = 313;\n        b.value314 = 314;\n        b.value315 = 315;\n        b.value316 = 316;\n        b.value317 = 317;\n        b.value318 = 318;\n        b.value319 = 319;\n        b.value320 = 320;\n        b.value321 = 321;\n        b.value322 = 322;\n        b.value323 = 323;\n        b.value324 = 324;\n        b.value325 = 325;\n        b.value326 = 326;\n        b.value327 = 327;\n        b.value328 = 328;\n        b.value329 = 329;\n        b.value330 = 330;\n        b.value331 = 331;\n        b.value332 = 332;\n        b.value333 = 333;\n        b.value334 = 334;\n        b.value335 = 335;\n        b.value336 = 336;\n        b.value337 = 337;\n        b.value338 = 338;\n        b.value339 = 339;\n        b.value340 = 340;\n        b.value341 = 341;\n        b.value342 = 342;\n        b.value343 = 343;\n        b.value344 = 344;\n        b.value345 = 345;\n        b.value346 = 346;\n        b.value347 = 347;\n        b.value348 = 348;\n        b.value349 = 349;\n        b.value350 = 350;\n        b.value351 = 351;\n        b.value352 = 352;\n        b.value353 = 353;\n        b.value354 = 354;\n        b.value355 = 355;\n        b.value356 = 356;\n        b.value357 = 357;\n        b.value358 = 358;\n        b.value359 = 359;\n        b.value360 = 360;\n        b.value361 = 361;\n        b.value362 = 362;\n        b.value363 = 363;\n        b.value364 = 364;\n        b.value365 = 365;\n        b.value366 = 366;\n        b.value367 = 367;\n        b.value368 = 368;\n        b.value369 = 369;\n        b.value370 = 370;\n        b.value371 = 371;\n        b.value372 = 372;\n        b.value373 = 373;\n        b.value374 = 374;\n        b.value375 = 375;\n        b.value376 = 376;\n        b.value377 = 377;\n        b.value378 = 378;\n        b.value379 = 379;\n        b.value380 = 380;\n        b.value381 = 381;\n        b.value382 = 382;\n        b.value383 = 383;\n        b.value384 = 384;\n        b.value385 = 385;\n        b.value386 = 386;\n        b.value387 = 387;\n        b.value388 = 388;\n        b.value389 = 389;\n        b.value390 = 390;\n        b.value391 = 391;\n        b.value392 = 392;\n        b.value393 = 393;\n        b.value394 = 394;\n        b.value395 = 395;\n        b.value396 = 396;\n        b.value397 = 397;\n        b.value398 = 398;\n        b.value399 = 399;\n        b.value400 = 400;\n        b.value401 = 401;\n        b.value402 = 402;\n        b.value403 = 403;\n        b.value404 = 404;\n        b.value405 = 405;\n        b.value406 = 406;\n        b.value407 = 407;\n        b.value408 = 408;\n        b.value409 = 409;\n        b.value410 = 410;\n        b.value411 = 411;\n        b.value412 = 412;\n        b.value413 = 413;\n        b.value414 = 414;\n        b.value415 = 415;\n        b.value416 = 416;\n        b.value417 = 417;\n        b.value418 = 418;\n        b.value419 = 419;\n        b.value420 = 420;\n        b.value421 = 421;\n        b.value422 = 422;\n        b.value423 = 423;\n        b.value424 = 424;\n        b.value425 = 425;\n        b.value426 = 426;\n        b.value427 = 427;\n        b.value428 = 428;\n        b.value429 = 429;\n        b.value430 = 430;\n        b.value431 = 431;\n        b.value432 = 432;\n        b.value433 = 433;\n        b.value434 = 434;\n        b.value435 = 435;\n        b.value436 = 436;\n        b.value437 = 437;\n        b.value438 = 438;\n        b.value439 = 439;\n        b.value440 = 440;\n        b.value441 = 441;\n        b.value442 = 442;\n        b.value443 = 443;\n        b.value444 = 444;\n        b.value445 = 445;\n        b.value446 = 446;\n        b.value447 = 447;\n        b.value448 = 448;\n        b.value449 = 449;\n        b.value450 = 450;\n        b.value451 = 451;\n        b.value452 = 452;\n        b.value453 = 453;\n        b.value454 = 454;\n        b.value455 = 455;\n        b.value456 = 456;\n        b.value457 = 457;\n        b.value458 = 458;\n        b.value459 = 459;\n        b.value460 = 460;\n        b.value461 = 461;\n        b.value462 = 462;\n        b.value463 = 463;\n        b.value464 = 464;\n        b.value465 = 465;\n        b.value466 = 466;\n        b.value467 = 467;\n        b.value468 = 468;\n        b.value469 = 469;\n        b.value470 = 470;\n        b.value471 = 471;\n        b.value472 = 472;\n        b.value473 = 473;\n        b.value474 = 474;\n        b.value475 = 475;\n        b.value476 = 476;\n        b.value477 = 477;\n        b.value478 = 478;\n        b.value479 = 479;\n        b.value480 = 480;\n        b.value481 = 481;\n        b.value482 = 482;\n        b.value483 = 483;\n        b.value484 = 484;\n        b.value485 = 485;\n        b.value486 = 486;\n        b.value487 = 487;\n        b.value488 = 488;\n        b.value489 = 489;\n        b.value490 = 490;\n        b.value491 = 491;\n        b.value492 = 492;\n        b.value493 = 493;\n        b.value494 = 494;\n        b.value495 = 495;\n        b.value496 = 496;\n        b.value497 = 497;\n        b.value498 = 498;\n        b.value499 = 499;\n        b.value500 = 500;\n        b.value501 = 501;\n        b.value502 = 502;\n        b.value503 = 503;\n        b.value504 = 504;\n        b.value505 = 505;\n        b.value506 = 506;\n        b.value507 = 507;\n        b.value508 = 508;\n        b.value509 = 509;\n        b.value510 = 510;\n        b.value511 = 511;\n        b.value512 = 512;\n        b.value513 = 513;\n        b.value514 = 514;\n        b.value515 = 515;\n        b.value516 = 516;\n        b.value517 = 517;\n        b.value518 = 518;\n        b.value519 = 519;\n        b.value520 = 520;\n        b.value521 = 521;\n        b.value522 = 522;\n        b.value523 = 523;\n        b.value524 = 524;\n        b.value525 = 525;\n        b.value526 = 526;\n        b.value527 = 527;\n        b.value528 = 528;\n        b.value529 = 529;\n        b.value530 = 530;\n        b.value531 = 531;\n        b.value532 = 532;\n        b.value533 = 533;\n        b.value534 = 534;\n        b.value535 = 535;\n        b.value536 = 536;\n        b.value537 = 537;\n        b.value538 = 538;\n        b.value539 = 539;\n        b.value540 = 540;\n        b.value541 = 541;\n        b.value542 = 542;\n        b.value543 = 543;\n        b.value544 = 544;\n        b.value545 = 545;\n        b.value546 = 546;\n        b.value547 = 547;\n        b.value548 = 548;\n        b.value549 = 549;\n        b.value550 = 550;\n        b.value551 = 551;\n        b.value552 = 552;\n        b.value553 = 553;\n        b.value554 = 554;\n        b.value555 = 555;\n        b.value556 = 556;\n        b.value557 = 557;\n        b.value558 = 558;\n        b.value559 = 559;\n        b.value560 = 560;\n        b.value561 = 561;\n        b.value562 = 562;\n        b.value563 = 563;\n        b.value564 = 564;\n        b.value565 = 565;\n        b.value566 = 566;\n        b.value567 = 567;\n        b.value568 = 568;\n        b.value569 = 569;\n        b.value570 = 570;\n        b.value571 = 571;\n        b.value572 = 572;\n        b.value573 = 573;\n        b.value574 = 574;\n        b.value575 = 575;\n        b.value576 = 576;\n        b.value577 = 577;\n        b.value578 = 578;\n        b.value579 = 579;\n        b.value580 = 580;\n        b.value581 = 581;\n        b.value582 = 582;\n        b.value583 = 583;\n        b.value584 = 584;\n        b.value585 = 585;\n        b.value586 = 586;\n        b.value587 = 587;\n        b.value588 = 588;\n        b.value589 = 589;\n        b.value590 = 590;\n        b.value591 = 591;\n        b.value592 = 592;\n        b.value593 = 593;\n        b.value594 = 594;\n        b.value595 = 595;\n        b.value596 = 596;\n        b.value597 = 597;\n        b.value598 = 598;\n        b.value599 = 599;\n        b.value600 = 600;\n        b.value601 = 601;\n        b.value602 = 602;\n        b.value603 = 603;\n        b.value604 = 604;\n        b.value605 = 605;\n        b.value606 = 606;\n        b.value607 = 607;\n        b.value608 = 608;\n        b.value609 = 609;\n        b.value610 = 610;\n        b.value611 = 611;\n        b.value612 = 612;\n        b.value613 = 613;\n        b.value614 = 614;\n        b.value615 = 615;\n        b.value616 = 616;\n        b.value617 = 617;\n        b.value618 = 618;\n        b.value619 = 619;\n        b.value620 = 620;\n        b.value621 = 621;\n        b.value622 = 622;\n        b.value623 = 623;\n        b.value624 = 624;\n        b.value625 = 625;\n        b.value626 = 626;\n        b.value627 = 627;\n        b.value628 = 628;\n        b.value629 = 629;\n        b.value630 = 630;\n        b.value631 = 631;\n        b.value632 = 632;\n        b.value633 = 633;\n        b.value634 = 634;\n        b.value635 = 635;\n        b.value636 = 636;\n        b.value637 = 637;\n        b.value638 = 638;\n        b.value639 = 639;\n        b.value640 = 640;\n        b.value641 = 641;\n        b.value642 = 642;\n        b.value643 = 643;\n        b.value644 = 644;\n        b.value645 = 645;\n        b.value646 = 646;\n        b.value647 = 647;\n        b.value648 = 648;\n        b.value649 = 649;\n        b.value650 = 650;\n        b.value651 = 651;\n        b.value652 = 652;\n        b.value653 = 653;\n        b.value654 = 654;\n        b.value655 = 655;\n        b.value656 = 656;\n        b.value657 = 657;\n        b.value658 = 658;\n        b.value659 = 659;\n        b.value660 = 660;\n        b.value661 = 661;\n        b.value662 = 662;\n        b.value663 = 663;\n        b.value664 = 664;\n        b.value665 = 665;\n        b.value666 = 666;\n        b.value667 = 667;\n        b.value668 = 668;\n        b.value669 = 669;\n        b.value670 = 670;\n        b.value671 = 671;\n        b.value672 = 672;\n        b.value673 = 673;\n        b.value674 = 674;\n        b.value675 = 675;\n        b.value676 = 676;\n        b.value677 = 677;\n        b.value678 = 678;\n        b.value679 = 679;\n        b.value680 = 680;\n        b.value681 = 681;\n        b.value682 = 682;\n        b.value683 = 683;\n        b.value684 = 684;\n        b.value685 = 685;\n        b.value686 = 686;\n        b.value687 = 687;\n        b.value688 = 688;\n        b.value689 = 689;\n        b.value690 = 690;\n        b.value691 = 691;\n        b.value692 = 692;\n        b.value693 = 693;\n        b.value694 = 694;\n        b.value695 = 695;\n        b.value696 = 696;\n        b.value697 = 697;\n        b.value698 = 698;\n        b.value699 = 699;\n        b.value700 = 700;\n        b.value701 = 701;\n        b.value702 = 702;\n        b.value703 = 703;\n        b.value704 = 704;\n        b.value705 = 705;\n        b.value706 = 706;\n        b.value707 = 707;\n        b.value708 = 708;\n        b.value709 = 709;\n        b.value710 = 710;\n        b.value711 = 711;\n        b.value712 = 712;\n        b.value713 = 713;\n        b.value714 = 714;\n        b.value715 = 715;\n        b.value716 = 716;\n        b.value717 = 717;\n        b.value718 = 718;\n        b.value719 = 719;\n        b.value720 = 720;\n        b.value721 = 721;\n        b.value722 = 722;\n        b.value723 = 723;\n        b.value724 = 724;\n        b.value725 = 725;\n        b.value726 = 726;\n        b.value727 = 727;\n        b.value728 = 728;\n        b.value729 = 729;\n        b.value730 = 730;\n        b.value731 = 731;\n        b.value732 = 732;\n        b.value733 = 733;\n        b.value734 = 734;\n        b.value735 = 735;\n        b.value736 = 736;\n        b.value737 = 737;\n        b.value738 = 738;\n        b.value739 = 739;\n        b.value740 = 740;\n        b.value741 = 741;\n        b.value742 = 742;\n        b.value743 = 743;\n        b.value744 = 744;\n        b.value745 = 745;\n        b.value746 = 746;\n        b.value747 = 747;\n        b.value748 = 748;\n        b.value749 = 749;\n        b.value750 = 750;\n        b.value751 = 751;\n        b.value752 = 752;\n        b.value753 = 753;\n        b.value754 = 754;\n        b.value755 = 755;\n        b.value756 = 756;\n        b.value757 = 757;\n        b.value758 = 758;\n        b.value759 = 759;\n        b.value760 = 760;\n        b.value761 = 761;\n        b.value762 = 762;\n        b.value763 = 763;\n        b.value764 = 764;\n        b.value765 = 765;\n        b.value766 = 766;\n        b.value767 = 767;\n        b.value768 = 768;\n        b.value769 = 769;\n        b.value770 = 770;\n        b.value771 = 771;\n        b.value772 = 772;\n        b.value773 = 773;\n        b.value774 = 774;\n        b.value775 = 775;\n        b.value776 = 776;\n        b.value777 = 777;\n        b.value778 = 778;\n        b.value779 = 779;\n        b.value780 = 780;\n        b.value781 = 781;\n        b.value782 = 782;\n        b.value783 = 783;\n        b.value784 = 784;\n        b.value785 = 785;\n        b.value786 = 786;\n        b.value787 = 787;\n        b.value788 = 788;\n        b.value789 = 789;\n        b.value790 = 790;\n        b.value791 = 791;\n        b.value792 = 792;\n        b.value793 = 793;\n        b.value794 = 794;\n        b.value795 = 795;\n        b.value796 = 796;\n        b.value797 = 797;\n        b.value798 = 798;\n        b.value799 = 799;\n        b.value800 = 800;\n        b.value801 = 801;\n        b.value802 = 802;\n        b.value803 = 803;\n        b.value804 = 804;\n        b.value805 = 805;\n        b.value806 = 806;\n        b.value807 = 807;\n        b.value808 = 808;\n        b.value809 = 809;\n        b.value810 = 810;\n        b.value811 = 811;\n        b.value812 = 812;\n        b.value813 = 813;\n        b.value814 = 814;\n        b.value815 = 815;\n        b.value816 = 816;\n        b.value817 = 817;\n        b.value818 = 818;\n        b.value819 = 819;\n        b.value820 = 820;\n        b.value821 = 821;\n        b.value822 = 822;\n        b.value823 = 823;\n        b.value824 = 824;\n        b.value825 = 825;\n        b.value826 = 826;\n        b.value827 = 827;\n        b.value828 = 828;\n        b.value829 = 829;\n        b.value830 = 830;\n        b.value831 = 831;\n        b.value832 = 832;\n        b.value833 = 833;\n        b.value834 = 834;\n        b.value835 = 835;\n        b.value836 = 836;\n        b.value837 = 837;\n        b.value838 = 838;\n        b.value839 = 839;\n        b.value840 = 840;\n        b.value841 = 841;\n        b.value842 = 842;\n        b.value843 = 843;\n        b.value844 = 844;\n        b.value845 = 845;\n        b.value846 = 846;\n        b.value847 = 847;\n        b.value848 = 848;\n        b.value849 = 849;\n        b.value850 = 850;\n        b.value851 = 851;\n        b.value852 = 852;\n        b.value853 = 853;\n        b.value854 = 854;\n        b.value855 = 855;\n        b.value856 = 856;\n        b.value857 = 857;\n        b.value858 = 858;\n        b.value859 = 859;\n        b.value860 = 860;\n        b.value861 = 861;\n        b.value862 = 862;\n        b.value863 = 863;\n        b.value864 = 864;\n        b.value865 = 865;\n        b.value866 = 866;\n        b.value867 = 867;\n        b.value868 = 868;\n        b.value869 = 869;\n        b.value870 = 870;\n        b.value871 = 871;\n        b.value872 = 872;\n        b.value873 = 873;\n        b.value874 = 874;\n        b.value875 = 875;\n        b.value876 = 876;\n        b.value877 = 877;\n        b.value878 = 878;\n        b.value879 = 879;\n        b.value880 = 880;\n        b.value881 = 881;\n        b.value882 = 882;\n        b.value883 = 883;\n        b.value884 = 884;\n        b.value885 = 885;\n        b.value886 = 886;\n        b.value887 = 887;\n        b.value888 = 888;\n        b.value889 = 889;\n        b.value890 = 890;\n        b.value891 = 891;\n        b.value892 = 892;\n        b.value893 = 893;\n        b.value894 = 894;\n        b.value895 = 895;\n        b.value896 = 896;\n        b.value897 = 897;\n        b.value898 = 898;\n        b.value899 = 899;\n        b.value900 = 900;\n        b.value901 = 901;\n        b.value902 = 902;\n        b.value903 = 903;\n        b.value904 = 904;\n        b.value905 = 905;\n        b.value906 = 906;\n        b.value907 = 907;\n        b.value908 = 908;\n        b.value909 = 909;\n        b.value910 = 910;\n        b.value911 = 911;\n        b.value912 = 912;\n        b.value913 = 913;\n        b.value914 = 914;\n        b.value915 = 915;\n        b.value916 = 916;\n        b.value917 = 917;\n        b.value918 = 918;\n        b.value919 = 919;\n        b.value920 = 920;\n        b.value921 = 921;\n        b.value922 = 922;\n        b.value923 = 923;\n        b.value924 = 924;\n        b.value925 = 925;\n        b.value926 = 926;\n        b.value927 = 927;\n        b.value928 = 928;\n        b.value929 = 929;\n        b.value930 = 930;\n        b.value931 = 931;\n        b.value932 = 932;\n        b.value933 = 933;\n        b.value934 = 934;\n        b.value935 = 935;\n        b.value936 = 936;\n        b.value937 = 937;\n        b.value938 = 938;\n        b.value939 = 939;\n        b.value940 = 940;\n        b.value941 = 941;\n        b.value942 = 942;\n        b.value943 = 943;\n        b.value944 = 944;\n        b.value945 = 945;\n        b.value946 = 946;\n        b.value947 = 947;\n        b.value948 = 948;\n        b.value949 = 949;\n        b.value950 = 950;\n        b.value951 = 951;\n        b.value952 = 952;\n        b.value953 = 953;\n        b.value954 = 954;\n        b.value955 = 955;\n        b.value956 = 956;\n        b.value957 = 957;\n        b.value958 = 958;\n        b.value959 = 959;\n        b.value960 = 960;\n        b.value961 = 961;\n        b.value962 = 962;\n        b.value963 = 963;\n        b.value964 = 964;\n        b.value965 = 965;\n        b.value966 = 966;\n        b.value967 = 967;\n        b.value968 = 968;\n        b.value969 = 969;\n        b.value970 = 970;\n        b.value971 = 971;\n        b.value972 = 972;\n        b.value973 = 973;\n        b.value974 = 974;\n        b.value975 = 975;\n        b.value976 = 976;\n        b.value977 = 977;\n        b.value978 = 978;\n        b.value979 = 979;\n        b.value980 = 980;\n        b.value981 = 981;\n        b.value982 = 982;\n        b.value983 = 983;\n        b.value984 = 984;\n        b.value985 = 985;\n        b.value986 = 986;\n        b.value987 = 987;\n        b.value988 = 988;\n        b.value989 = 989;\n        b.value990 = 990;\n        b.value991 = 991;\n        b.value992 = 992;\n        b.value993 = 993;\n        b.value994 = 994;\n        b.value995 = 995;\n        b.value996 = 996;\n        b.value997 = 997;\n        b.value998 = 998;\n        b.value999 = 999;\n        b.value1000 = 1000;\n        b.value1001 = 1001;\n        b.value1002 = 1002;\n        b.value1003 = 1003;\n        b.value1004 = 1004;\n        b.value1005 = 1005;\n        b.value1006 = 1006;\n        b.value1007 = 1007;\n        b.value1008 = 1008;\n        b.value1009 = 1009;\n        b.value1010 = 1010;\n        b.value1011 = 1011;\n        b.value1012 = 1012;\n        b.value1013 = 1013;\n        b.value1014 = 1014;\n        b.value1015 = 1015;\n        b.value1016 = 1016;\n        b.value1017 = 1017;\n        b.value1018 = 1018;\n        b.value1019 = 1019;\n        b.value1020 = 1020;\n        b.value1021 = 1021;\n        b.value1022 = 1022;\n        b.value1023 = 1023;\n        b.value1024 = 1024;\n        b.value1025 = 1025;\n        b.value1026 = 1026;\n        b.value1027 = 1027;\n        b.value1028 = 1028;\n        b.value1029 = 1029;\n        b.value1030 = 1030;\n        b.value1031 = 1031;\n        b.value1032 = 1032;\n        b.value1033 = 1033;\n        b.value1034 = 1034;\n        b.value1035 = 1035;\n        b.value1036 = 1036;\n        b.value1037 = 1037;\n        b.value1038 = 1038;\n        b.value1039 = 1039;\n        b.value1040 = 1040;\n        b.value1041 = 1041;\n        b.value1042 = 1042;\n        b.value1043 = 1043;\n        b.value1044 = 1044;\n        b.value1045 = 1045;\n        b.value1046 = 1046;\n        b.value1047 = 1047;\n        b.value1048 = 1048;\n        b.value1049 = 1049;\n        b.value1050 = 1050;\n        b.value1051 = 1051;\n        b.value1052 = 1052;\n        b.value1053 = 1053;\n        b.value1054 = 1054;\n        b.value1055 = 1055;\n        b.value1056 = 1056;\n        b.value1057 = 1057;\n        b.value1058 = 1058;\n        b.value1059 = 1059;\n        b.value1060 = 1060;\n        b.value1061 = 1061;\n        b.value1062 = 1062;\n        b.value1063 = 1063;\n        b.value1064 = 1064;\n        b.value1065 = 1065;\n        b.value1066 = 1066;\n        b.value1067 = 1067;\n        b.value1068 = 1068;\n        b.value1069 = 1069;\n        b.value1070 = 1070;\n        b.value1071 = 1071;\n        b.value1072 = 1072;\n        b.value1073 = 1073;\n        b.value1074 = 1074;\n        b.value1075 = 1075;\n        b.value1076 = 1076;\n        b.value1077 = 1077;\n        b.value1078 = 1078;\n        b.value1079 = 1079;\n        b.value1080 = 1080;\n        b.value1081 = 1081;\n        b.value1082 = 1082;\n        b.value1083 = 1083;\n        b.value1084 = 1084;\n        b.value1085 = 1085;\n        b.value1086 = 1086;\n        b.value1087 = 1087;\n        b.value1088 = 1088;\n        b.value1089 = 1089;\n        b.value1090 = 1090;\n        b.value1091 = 1091;\n        b.value1092 = 1092;\n        b.value1093 = 1093;\n        b.value1094 = 1094;\n        b.value1095 = 1095;\n        b.value1096 = 1096;\n        b.value1097 = 1097;\n        b.value1098 = 1098;\n        b.value1099 = 1099;\n        b.value1100 = 1100;\n        b.value1101 = 1101;\n        b.value1102 = 1102;\n        b.value1103 = 1103;\n        b.value1104 = 1104;\n        b.value1105 = 1105;\n        b.value1106 = 1106;\n        b.value1107 = 1107;\n        b.value1108 = 1108;\n        b.value1109 = 1109;\n        b.value1110 = 1110;\n        b.value1111 = 1111;\n        b.value1112 = 1112;\n        b.value1113 = 1113;\n        b.value1114 = 1114;\n        b.value1115 = 1115;\n        b.value1116 = 1116;\n        b.value1117 = 1117;\n        b.value1118 = 1118;\n        b.value1119 = 1119;\n        b.value1120 = 1120;\n        b.value1121 = 1121;\n        b.value1122 = 1122;\n        b.value1123 = 1123;\n        b.value1124 = 1124;\n        b.value1125 = 1125;\n        b.value1126 = 1126;\n        b.value1127 = 1127;\n        b.value1128 = 1128;\n        b.value1129 = 1129;\n        b.value1130 = 1130;\n        b.value1131 = 1131;\n        b.value1132 = 1132;\n        b.value1133 = 1133;\n        b.value1134 = 1134;\n        b.value1135 = 1135;\n        b.value1136 = 1136;\n        b.value1137 = 1137;\n        b.value1138 = 1138;\n        b.value1139 = 1139;\n        b.value1140 = 1140;\n        b.value1141 = 1141;\n        b.value1142 = 1142;\n        b.value1143 = 1143;\n        b.value1144 = 1144;\n        b.value1145 = 1145;\n        b.value1146 = 1146;\n        b.value1147 = 1147;\n        b.value1148 = 1148;\n        b.value1149 = 1149;\n        b.value1150 = 1150;\n        b.value1151 = 1151;\n        b.value1152 = 1152;\n        b.value1153 = 1153;\n        b.value1154 = 1154;\n        b.value1155 = 1155;\n        b.value1156 = 1156;\n        b.value1157 = 1157;\n        b.value1158 = 1158;\n        b.value1159 = 1159;\n        b.value1160 = 1160;\n        b.value1161 = 1161;\n        b.value1162 = 1162;\n        b.value1163 = 1163;\n        b.value1164 = 1164;\n        b.value1165 = 1165;\n        b.value1166 = 1166;\n        b.value1167 = 1167;\n        b.value1168 = 1168;\n        b.value1169 = 1169;\n        b.value1170 = 1170;\n        b.value1171 = 1171;\n        b.value1172 = 1172;\n        b.value1173 = 1173;\n        b.value1174 = 1174;\n        b.value1175 = 1175;\n        b.value1176 = 1176;\n        b.value1177 = 1177;\n        b.value1178 = 1178;\n        b.value1179 = 1179;\n        b.value1180 = 1180;\n        b.value1181 = 1181;\n        b.value1182 = 1182;\n        b.value1183 = 1183;\n        b.value1184 = 1184;\n        b.value1185 = 1185;\n        b.value1186 = 1186;\n        b.value1187 = 1187;\n        b.value1188 = 1188;\n        b.value1189 = 1189;\n        b.value1190 = 1190;\n        b.value1191 = 1191;\n        b.value1192 = 1192;\n        b.value1193 = 1193;\n        b.value1194 = 1194;\n        b.value1195 = 1195;\n        b.value1196 = 1196;\n        b.value1197 = 1197;\n        b.value1198 = 1198;\n        b.value1199 = 1199;\n        b.value1200 = 1200;\n        b.value1201 = 1201;\n        b.value1202 = 1202;\n        b.value1203 = 1203;\n        b.value1204 = 1204;\n        b.value1205 = 1205;\n        b.value1206 = 1206;\n        b.value1207 = 1207;\n        b.value1208 = 1208;\n        b.value1209 = 1209;\n        b.value1210 = 1210;\n        b.value1211 = 1211;\n        b.value1212 = 1212;\n        b.value1213 = 1213;\n        b.value1214 = 1214;\n        b.value1215 = 1215;\n        b.value1216 = 1216;\n        b.value1217 = 1217;\n        b.value1218 = 1218;\n        b.value1219 = 1219;\n        b.value1220 = 1220;\n        b.value1221 = 1221;\n        b.value1222 = 1222;\n        b.value1223 = 1223;\n        b.value1224 = 1224;\n        b.value1225 = 1225;\n        b.value1226 = 1226;\n        b.value1227 = 1227;\n        b.value1228 = 1228;\n        b.value1229 = 1229;\n        b.value1230 = 1230;\n        b.value1231 = 1231;\n        b.value1232 = 1232;\n        b.value1233 = 1233;\n        b.value1234 = 1234;\n        b.value1235 = 1235;\n        b.value1236 = 1236;\n        b.value1237 = 1237;\n        b.value1238 = 1238;\n        b.value1239 = 1239;\n        b.value1240 = 1240;\n        b.value1241 = 1241;\n        b.value1242 = 1242;\n        b.value1243 = 1243;\n        b.value1244 = 1244;\n        b.value1245 = 1245;\n        b.value1246 = 1246;\n        b.value1247 = 1247;\n        b.value1248 = 1248;\n        b.value1249 = 1249;\n        b.value1250 = 1250;\n        b.value1251 = 1251;\n        b.value1252 = 1252;\n        b.value1253 = 1253;\n        b.value1254 = 1254;\n        b.value1255 = 1255;\n        b.value1256 = 1256;\n        b.value1257 = 1257;\n        b.value1258 = 1258;\n        b.value1259 = 1259;\n        b.value1260 = 1260;\n        b.value1261 = 1261;\n        b.value1262 = 1262;\n        b.value1263 = 1263;\n        b.value1264 = 1264;\n        b.value1265 = 1265;\n        b.value1266 = 1266;\n        b.value1267 = 1267;\n        b.value1268 = 1268;\n        b.value1269 = 1269;\n        b.value1270 = 1270;\n        b.value1271 = 1271;\n        b.value1272 = 1272;\n        b.value1273 = 1273;\n        b.value1274 = 1274;\n        b.value1275 = 1275;\n        b.value1276 = 1276;\n        b.value1277 = 1277;\n        b.value1278 = 1278;\n        b.value1279 = 1279;\n        b.value1280 = 1280;\n        b.value1281 = 1281;\n        b.value1282 = 1282;\n        b.value1283 = 1283;\n        b.value1284 = 1284;\n        b.value1285 = 1285;\n        b.value1286 = 1286;\n        b.value1287 = 1287;\n        b.value1288 = 1288;\n        b.value1289 = 1289;\n        b.value1290 = 1290;\n        b.value1291 = 1291;\n        b.value1292 = 1292;\n        b.value1293 = 1293;\n        b.value1294 = 1294;\n        b.value1295 = 1295;\n        b.value1296 = 1296;\n        b.value1297 = 1297;\n        b.value1298 = 1298;\n        b.value1299 = 1299;\n        b.value1300 = 1300;\n        b.value1301 = 1301;\n        b.value1302 = 1302;\n        b.value1303 = 1303;\n        b.value1304 = 1304;\n        b.value1305 = 1305;\n        b.value1306 = 1306;\n        b.value1307 = 1307;\n        b.value1308 = 1308;\n        b.value1309 = 1309;\n        b.value1310 = 1310;\n        b.value1311 = 1311;\n        b.value1312 = 1312;\n        b.value1313 = 1313;\n        b.value1314 = 1314;\n        b.value1315 = 1315;\n        b.value1316 = 1316;\n        b.value1317 = 1317;\n        b.value1318 = 1318;\n        b.value1319 = 1319;\n        b.value1320 = 1320;\n        b.value1321 = 1321;\n        b.value1322 = 1322;\n        b.value1323 = 1323;\n        b.value1324 = 1324;\n        b.value1325 = 1325;\n        b.value1326 = 1326;\n        b.value1327 = 1327;\n        b.value1328 = 1328;\n        b.value1329 = 1329;\n        b.value1330 = 1330;\n        b.value1331 = 1331;\n        b.value1332 = 1332;\n        b.value1333 = 1333;\n        b.value1334 = 1334;\n        b.value1335 = 1335;\n        b.value1336 = 1336;\n        b.value1337 = 1337;\n        b.value1338 = 1338;\n        b.value1339 = 1339;\n        b.value1340 = 1340;\n        b.value1341 = 1341;\n        b.value1342 = 1342;\n        b.value1343 = 1343;\n        b.value1344 = 1344;\n        b.value1345 = 1345;\n        b.value1346 = 1346;\n        b.value1347 = 1347;\n        b.value1348 = 1348;\n        b.value1349 = 1349;\n        b.value1350 = 1350;\n        b.value1351 = 1351;\n        b.value1352 = 1352;\n        b.value1353 = 1353;\n        b.value1354 = 1354;\n        b.value1355 = 1355;\n        b.value1356 = 1356;\n        b.value1357 = 1357;\n        b.value1358 = 1358;\n        b.value1359 = 1359;\n        b.value1360 = 1360;\n        b.value1361 = 1361;\n        b.value1362 = 1362;\n        b.value1363 = 1363;\n        b.value1364 = 1364;\n        b.value1365 = 1365;\n        b.value1366 = 1366;\n        b.value1367 = 1367;\n        b.value1368 = 1368;\n        b.value1369 = 1369;\n        b.value1370 = 1370;\n        b.value1371 = 1371;\n        b.value1372 = 1372;\n        b.value1373 = 1373;\n        b.value1374 = 1374;\n        b.value1375 = 1375;\n        b.value1376 = 1376;\n        b.value1377 = 1377;\n        b.value1378 = 1378;\n        b.value1379 = 1379;\n        b.value1380 = 1380;\n        b.value1381 = 1381;\n        b.value1382 = 1382;\n        b.value1383 = 1383;\n        b.value1384 = 1384;\n        b.value1385 = 1385;\n        b.value1386 = 1386;\n        b.value1387 = 1387;\n        b.value1388 = 1388;\n        b.value1389 = 1389;\n        b.value1390 = 1390;\n        b.value1391 = 1391;\n        b.value1392 = 1392;\n        b.value1393 = 1393;\n        b.value1394 = 1394;\n        b.value1395 = 1395;\n        b.value1396 = 1396;\n        b.value1397 = 1397;\n        b.value1398 = 1398;\n        b.value1399 = 1399;\n        b.value1400 = 1400;\n        b.value1401 = 1401;\n        b.value1402 = 1402;\n        b.value1403 = 1403;\n        b.value1404 = 1404;\n        b.value1405 = 1405;\n        b.value1406 = 1406;\n        b.value1407 = 1407;\n        b.value1408 = 1408;\n        b.value1409 = 1409;\n        b.value1410 = 1410;\n        b.value1411 = 1411;\n        b.value1412 = 1412;\n        b.value1413 = 1413;\n        b.value1414 = 1414;\n        b.value1415 = 1415;\n        b.value1416 = 1416;\n        b.value1417 = 1417;\n        b.value1418 = 1418;\n        b.value1419 = 1419;\n        b.value1420 = 1420;\n        b.value1421 = 1421;\n        b.value1422 = 1422;\n        b.value1423 = 1423;\n        b.value1424 = 1424;\n        b.value1425 = 1425;\n        b.value1426 = 1426;\n        b.value1427 = 1427;\n        b.value1428 = 1428;\n        b.value1429 = 1429;\n        b.value1430 = 1430;\n        b.value1431 = 1431;\n        b.value1432 = 1432;\n        b.value1433 = 1433;\n        b.value1434 = 1434;\n        b.value1435 = 1435;\n        b.value1436 = 1436;\n        b.value1437 = 1437;\n        b.value1438 = 1438;\n        b.value1439 = 1439;\n        b.value1440 = 1440;\n        b.value1441 = 1441;\n        b.value1442 = 1442;\n        b.value1443 = 1443;\n        b.value1444 = 1444;\n        b.value1445 = 1445;\n        b.value1446 = 1446;\n        b.value1447 = 1447;\n        b.value1448 = 1448;\n        b.value1449 = 1449;\n        b.value1450 = 1450;\n        b.value1451 = 1451;\n        b.value1452 = 1452;\n        b.value1453 = 1453;\n        b.value1454 = 1454;\n        b.value1455 = 1455;\n        b.value1456 = 1456;\n        b.value1457 = 1457;\n        b.value1458 = 1458;\n        b.value1459 = 1459;\n        b.value1460 = 1460;\n        b.value1461 = 1461;\n        b.value1462 = 1462;\n        b.value1463 = 1463;\n        b.value1464 = 1464;\n        b.value1465 = 1465;\n        b.value1466 = 1466;\n        b.value1467 = 1467;\n        b.value1468 = 1468;\n        b.value1469 = 1469;\n        b.value1470 = 1470;\n        b.value1471 = 1471;\n        b.value1472 = 1472;\n        b.value1473 = 1473;\n        b.value1474 = 1474;\n        b.value1475 = 1475;\n        b.value1476 = 1476;\n        b.value1477 = 1477;\n        b.value1478 = 1478;\n        b.value1479 = 1479;\n        b.value1480 = 1480;\n        b.value1481 = 1481;\n        b.value1482 = 1482;\n        b.value1483 = 1483;\n        b.value1484 = 1484;\n        b.value1485 = 1485;\n        b.value1486 = 1486;\n        b.value1487 = 1487;\n        b.value1488 = 1488;\n        b.value1489 = 1489;\n        b.value1490 = 1490;\n        b.value1491 = 1491;\n        b.value1492 = 1492;\n        b.value1493 = 1493;\n        b.value1494 = 1494;\n        b.value1495 = 1495;\n        b.value1496 = 1496;\n        b.value1497 = 1497;\n        b.value1498 = 1498;\n        b.value1499 = 1499;\n        b.value1500 = 1500;\n        b.value1501 = 1501;\n        b.value1502 = 1502;\n        b.value1503 = 1503;\n        b.value1504 = 1504;\n        b.value1505 = 1505;\n        b.value1506 = 1506;\n        b.value1507 = 1507;\n        b.value1508 = 1508;\n        b.value1509 = 1509;\n        b.value1510 = 1510;\n        b.value1511 = 1511;\n        b.value1512 = 1512;\n        b.value1513 = 1513;\n        b.value1514 = 1514;\n        b.value1515 = 1515;\n        b.value1516 = 1516;\n        b.value1517 = 1517;\n        b.value1518 = 1518;\n        b.value1519 = 1519;\n        b.value1520 = 1520;\n        b.value1521 = 1521;\n        b.value1522 = 1522;\n        b.value1523 = 1523;\n        b.value1524 = 1524;\n        b.value1525 = 1525;\n        b.value1526 = 1526;\n        b.value1527 = 1527;\n        b.value1528 = 1528;\n        b.value1529 = 1529;\n        b.value1530 = 1530;\n        b.value1531 = 1531;\n        b.value1532 = 1532;\n        b.value1533 = 1533;\n        b.value1534 = 1534;\n        b.value1535 = 1535;\n        b.value1536 = 1536;\n        b.value1537 = 1537;\n        b.value1538 = 1538;\n        b.value1539 = 1539;\n        b.value1540 = 1540;\n        b.value1541 = 1541;\n        b.value1542 = 1542;\n        b.value1543 = 1543;\n        b.value1544 = 1544;\n        b.value1545 = 1545;\n        b.value1546 = 1546;\n        b.value1547 = 1547;\n        b.value1548 = 1548;\n        b.value1549 = 1549;\n        b.value1550 = 1550;\n        b.value1551 = 1551;\n        b.value1552 = 1552;\n        b.value1553 = 1553;\n        b.value1554 = 1554;\n        b.value1555 = 1555;\n        b.value1556 = 1556;\n        b.value1557 = 1557;\n        b.value1558 = 1558;\n        b.value1559 = 1559;\n        b.value1560 = 1560;\n        b.value1561 = 1561;\n        b.value1562 = 1562;\n        b.value1563 = 1563;\n        b.value1564 = 1564;\n        b.value1565 = 1565;\n        b.value1566 = 1566;\n        b.value1567 = 1567;\n        b.value1568 = 1568;\n        b.value1569 = 1569;\n        b.value1570 = 1570;\n        b.value1571 = 1571;\n        b.value1572 = 1572;\n        b.value1573 = 1573;\n        b.value1574 = 1574;\n        b.value1575 = 1575;\n        b.value1576 = 1576;\n        b.value1577 = 1577;\n        b.value1578 = 1578;\n        b.value1579 = 1579;\n        b.value1580 = 1580;\n        b.value1581 = 1581;\n        b.value1582 = 1582;\n        b.value1583 = 1583;\n        b.value1584 = 1584;\n        b.value1585 = 1585;\n        b.value1586 = 1586;\n        b.value1587 = 1587;\n        b.value1588 = 1588;\n        b.value1589 = 1589;\n        b.value1590 = 1590;\n        b.value1591 = 1591;\n        b.value1592 = 1592;\n        b.value1593 = 1593;\n        b.value1594 = 1594;\n        b.value1595 = 1595;\n        b.value1596 = 1596;\n        b.value1597 = 1597;\n        b.value1598 = 1598;\n        b.value1599 = 1599;\n        b.value1600 = 1600;\n        b.value1601 = 1601;\n        b.value1602 = 1602;\n        b.value1603 = 1603;\n        b.value1604 = 1604;\n        b.value1605 = 1605;\n        b.value1606 = 1606;\n        b.value1607 = 1607;\n        b.value1608 = 1608;\n        b.value1609 = 1609;\n        b.value1610 = 1610;\n        b.value1611 = 1611;\n        b.value1612 = 1612;\n        b.value1613 = 1613;\n        b.value1614 = 1614;\n        b.value1615 = 1615;\n        b.value1616 = 1616;\n        b.value1617 = 1617;\n        b.value1618 = 1618;\n        b.value1619 = 1619;\n        b.value1620 = 1620;\n        b.value1621 = 1621;\n        b.value1622 = 1622;\n        b.value1623 = 1623;\n        b.value1624 = 1624;\n        b.value1625 = 1625;\n        b.value1626 = 1626;\n        b.value1627 = 1627;\n        b.value1628 = 1628;\n        b.value1629 = 1629;\n        b.value1630 = 1630;\n        b.value1631 = 1631;\n        b.value1632 = 1632;\n        b.value1633 = 1633;\n        b.value1634 = 1634;\n        b.value1635 = 1635;\n        b.value1636 = 1636;\n        b.value1637 = 1637;\n        b.value1638 = 1638;\n        b.value1639 = 1639;\n        b.value1640 = 1640;\n        b.value1641 = 1641;\n        b.value1642 = 1642;\n        b.value1643 = 1643;\n        b.value1644 = 1644;\n        b.value1645 = 1645;\n        b.value1646 = 1646;\n        b.value1647 = 1647;\n        b.value1648 = 1648;\n        b.value1649 = 1649;\n        b.value1650 = 1650;\n        b.value1651 = 1651;\n        b.value1652 = 1652;\n        b.value1653 = 1653;\n        b.value1654 = 1654;\n        b.value1655 = 1655;\n        b.value1656 = 1656;\n        b.value1657 = 1657;\n        b.value1658 = 1658;\n        b.value1659 = 1659;\n        b.value1660 = 1660;\n        b.value1661 = 1661;\n        b.value1662 = 1662;\n        b.value1663 = 1663;\n        b.value1664 = 1664;\n        b.value1665 = 1665;\n        b.value1666 = 1666;\n        b.value1667 = 1667;\n        b.value1668 = 1668;\n        b.value1669 = 1669;\n        b.value1670 = 1670;\n        b.value1671 = 1671;\n        b.value1672 = 1672;\n        b.value1673 = 1673;\n        b.value1674 = 1674;\n        b.value1675 = 1675;\n        b.value1676 = 1676;\n        b.value1677 = 1677;\n        b.value1678 = 1678;\n        b.value1679 = 1679;\n        b.value1680 = 1680;\n        b.value1681 = 1681;\n        b.value1682 = 1682;\n        b.value1683 = 1683;\n        b.value1684 = 1684;\n        b.value1685 = 1685;\n        b.value1686 = 1686;\n        b.value1687 = 1687;\n        b.value1688 = 1688;\n        b.value1689 = 1689;\n        b.value1690 = 1690;\n        b.value1691 = 1691;\n        b.value1692 = 1692;\n        b.value1693 = 1693;\n        b.value1694 = 1694;\n        b.value1695 = 1695;\n        b.value1696 = 1696;\n        b.value1697 = 1697;\n        b.value1698 = 1698;\n        b.value1699 = 1699;\n        b.value1700 = 1700;\n        b.value1701 = 1701;\n        b.value1702 = 1702;\n        b.value1703 = 1703;\n        b.value1704 = 1704;\n        b.value1705 = 1705;\n        b.value1706 = 1706;\n        b.value1707 = 1707;\n        b.value1708 = 1708;\n        b.value1709 = 1709;\n        b.value1710 = 1710;\n        b.value1711 = 1711;\n        b.value1712 = 1712;\n        b.value1713 = 1713;\n        b.value1714 = 1714;\n        b.value1715 = 1715;\n        b.value1716 = 1716;\n        b.value1717 = 1717;\n        b.value1718 = 1718;\n        b.value1719 = 1719;\n        b.value1720 = 1720;\n        b.value1721 = 1721;\n        b.value1722 = 1722;\n        b.value1723 = 1723;\n        b.value1724 = 1724;\n        b.value1725 = 1725;\n        b.value1726 = 1726;\n        b.value1727 = 1727;\n        b.value1728 = 1728;\n        b.value1729 = 1729;\n        b.value1730 = 1730;\n        b.value1731 = 1731;\n        b.value1732 = 1732;\n        b.value1733 = 1733;\n        b.value1734 = 1734;\n        b.value1735 = 1735;\n        b.value1736 = 1736;\n        b.value1737 = 1737;\n        b.value1738 = 1738;\n        b.value1739 = 1739;\n        b.value1740 = 1740;\n        b.value1741 = 1741;\n        b.value1742 = 1742;\n        b.value1743 = 1743;\n        b.value1744 = 1744;\n        b.value1745 = 1745;\n        b.value1746 = 1746;\n        b.value1747 = 1747;\n        b.value1748 = 1748;\n        b.value1749 = 1749;\n        b.value1750 = 1750;\n        b.value1751 = 1751;\n        b.value1752 = 1752;\n        b.value1753 = 1753;\n        b.value1754 = 1754;\n        b.value1755 = 1755;\n        b.value1756 = 1756;\n        b.value1757 = 1757;\n        b.value1758 = 1758;\n        b.value1759 = 1759;\n        b.value1760 = 1760;\n        b.value1761 = 1761;\n        b.value1762 = 1762;\n        b.value1763 = 1763;\n        b.value1764 = 1764;\n        b.value1765 = 1765;\n        b.value1766 = 1766;\n        b.value1767 = 1767;\n        b.value1768 = 1768;\n        b.value1769 = 1769;\n        b.value1770 = 1770;\n        b.value1771 = 1771;\n        b.value1772 = 1772;\n        b.value1773 = 1773;\n        b.value1774 = 1774;\n        b.value1775 = 1775;\n        b.value1776 = 1776;\n        b.value1777 = 1777;\n        b.value1778 = 1778;\n        b.value1779 = 1779;\n        b.value1780 = 1780;\n        b.value1781 = 1781;\n        b.value1782 = 1782;\n        b.value1783 = 1783;\n        b.value1784 = 1784;\n        b.value1785 = 1785;\n        b.value1786 = 1786;\n        b.value1787 = 1787;\n        b.value1788 = 1788;\n        b.value1789 = 1789;\n        b.value1790 = 1790;\n        b.value1791 = 1791;\n        b.value1792 = 1792;\n        b.value1793 = 1793;\n        b.value1794 = 1794;\n        b.value1795 = 1795;\n        b.value1796 = 1796;\n        b.value1797 = 1797;\n        b.value1798 = 1798;\n        b.value1799 = 1799;\n        b.value1800 = 1800;\n        b.value1801 = 1801;\n        b.value1802 = 1802;\n        b.value1803 = 1803;\n        b.value1804 = 1804;\n        b.value1805 = 1805;\n        b.value1806 = 1806;\n        b.value1807 = 1807;\n        b.value1808 = 1808;\n        b.value1809 = 1809;\n        b.value1810 = 1810;\n        b.value1811 = 1811;\n        b.value1812 = 1812;\n        b.value1813 = 1813;\n        b.value1814 = 1814;\n        b.value1815 = 1815;\n        b.value1816 = 1816;\n        b.value1817 = 1817;\n        b.value1818 = 1818;\n        b.value1819 = 1819;\n        b.value1820 = 1820;\n        b.value1821 = 1821;\n        b.value1822 = 1822;\n        b.value1823 = 1823;\n        b.value1824 = 1824;\n        b.value1825 = 1825;\n        b.value1826 = 1826;\n        b.value1827 = 1827;\n        b.value1828 = 1828;\n        b.value1829 = 1829;\n        b.value1830 = 1830;\n        b.value1831 = 1831;\n        b.value1832 = 1832;\n        b.value1833 = 1833;\n        b.value1834 = 1834;\n        b.value1835 = 1835;\n        b.value1836 = 1836;\n        b.value1837 = 1837;\n        b.value1838 = 1838;\n        b.value1839 = 1839;\n        b.value1840 = 1840;\n        b.value1841 = 1841;\n        b.value1842 = 1842;\n        b.value1843 = 1843;\n        b.value1844 = 1844;\n        b.value1845 = 1845;\n        b.value1846 = 1846;\n        b.value1847 = 1847;\n        b.value1848 = 1848;\n        b.value1849 = 1849;\n        b.value1850 = 1850;\n        b.value1851 = 1851;\n        b.value1852 = 1852;\n        b.value1853 = 1853;\n        b.value1854 = 1854;\n        b.value1855 = 1855;\n        b.value1856 = 1856;\n        b.value1857 = 1857;\n        b.value1858 = 1858;\n        b.value1859 = 1859;\n        b.value1860 = 1860;\n        b.value1861 = 1861;\n        b.value1862 = 1862;\n        b.value1863 = 1863;\n        b.value1864 = 1864;\n        b.value1865 = 1865;\n        b.value1866 = 1866;\n        b.value1867 = 1867;\n        b.value1868 = 1868;\n        b.value1869 = 1869;\n        b.value1870 = 1870;\n        b.value1871 = 1871;\n        b.value1872 = 1872;\n        b.value1873 = 1873;\n        b.value1874 = 1874;\n        b.value1875 = 1875;\n        b.value1876 = 1876;\n        b.value1877 = 1877;\n        b.value1878 = 1878;\n        b.value1879 = 1879;\n        b.value1880 = 1880;\n        b.value1881 = 1881;\n        b.value1882 = 1882;\n        b.value1883 = 1883;\n        b.value1884 = 1884;\n        b.value1885 = 1885;\n        b.value1886 = 1886;\n        b.value1887 = 1887;\n        b.value1888 = 1888;\n        b.value1889 = 1889;\n        b.value1890 = 1890;\n        b.value1891 = 1891;\n        b.value1892 = 1892;\n        b.value1893 = 1893;\n        b.value1894 = 1894;\n        b.value1895 = 1895;\n        b.value1896 = 1896;\n        b.value1897 = 1897;\n        b.value1898 = 1898;\n        b.value1899 = 1899;\n        b.value1900 = 1900;\n        b.value1901 = 1901;\n        b.value1902 = 1902;\n        b.value1903 = 1903;\n        b.value1904 = 1904;\n        b.value1905 = 1905;\n        b.value1906 = 1906;\n        b.value1907 = 1907;\n        b.value1908 = 1908;\n        b.value1909 = 1909;\n        b.value1910 = 1910;\n        b.value1911 = 1911;\n        b.value1912 = 1912;\n        b.value1913 = 1913;\n        b.value1914 = 1914;\n        b.value1915 = 1915;\n        b.value1916 = 1916;\n        b.value1917 = 1917;\n        b.value1918 = 1918;\n        b.value1919 = 1919;\n        b.value1920 = 1920;\n        b.value1921 = 1921;\n        b.value1922 = 1922;\n        b.value1923 = 1923;\n        b.value1924 = 1924;\n        b.value1925 = 1925;\n        b.value1926 = 1926;\n        b.value1927 = 1927;\n        b.value1928 = 1928;\n        b.value1929 = 1929;\n        b.value1930 = 1930;\n        b.value1931 = 1931;\n        b.value1932 = 1932;\n        b.value1933 = 1933;\n        b.value1934 = 1934;\n        b.value1935 = 1935;\n        b.value1936 = 1936;\n        b.value1937 = 1937;\n        b.value1938 = 1938;\n        b.value1939 = 1939;\n        b.value1940 = 1940;\n        b.value1941 = 1941;\n        b.value1942 = 1942;\n        b.value1943 = 1943;\n        b.value1944 = 1944;\n        b.value1945 = 1945;\n        b.value1946 = 1946;\n        b.value1947 = 1947;\n        b.value1948 = 1948;\n        b.value1949 = 1949;\n        b.value1950 = 1950;\n        b.value1951 = 1951;\n        b.value1952 = 1952;\n        b.value1953 = 1953;\n        b.value1954 = 1954;\n        b.value1955 = 1955;\n        b.value1956 = 1956;\n        b.value1957 = 1957;\n        b.value1958 = 1958;\n        b.value1959 = 1959;\n        b.value1960 = 1960;\n        b.value1961 = 1961;\n        b.value1962 = 1962;\n        b.value1963 = 1963;\n        b.value1964 = 1964;\n        b.value1965 = 1965;\n        b.value1966 = 1966;\n        b.value1967 = 1967;\n        b.value1968 = 1968;\n        b.value1969 = 1969;\n        b.value1970 = 1970;\n        b.value1971 = 1971;\n        b.value1972 = 1972;\n        b.value1973 = 1973;\n        b.value1974 = 1974;\n        b.value1975 = 1975;\n        b.value1976 = 1976;\n        b.value1977 = 1977;\n        b.value1978 = 1978;\n        b.value1979 = 1979;\n        b.value1980 = 1980;\n        b.value1981 = 1981;\n        b.value1982 = 1982;\n        b.value1983 = 1983;\n        b.value1984 = 1984;\n        b.value1985 = 1985;\n        b.value1986 = 1986;\n        b.value1987 = 1987;\n        b.value1988 = 1988;\n        b.value1989 = 1989;\n        b.value1990 = 1990;\n        b.value1991 = 1991;\n        b.value1992 = 1992;\n        b.value1993 = 1993;\n        b.value1994 = 1994;\n        b.value1995 = 1995;\n        b.value1996 = 1996;\n        b.value1997 = 1997;\n        b.value1998 = 1998;\n        b.value1999 = 1999;\n        b.value2000 = 2000;\n        b.value2001 = 2001;\n        b.value2002 = 2002;\n        b.value2003 = 2003;\n        b.value2004 = 2004;\n        b.value2005 = 2005;\n        b.value2006 = 2006;\n        b.value2007 = 2007;\n        b.value2008 = 2008;\n        b.value2009 = 2009;\n        b.value2010 = 2010;\n        b.value2011 = 2011;\n        b.value2012 = 2012;\n        b.value2013 = 2013;\n        b.value2014 = 2014;\n        b.value2015 = 2015;\n        b.value2016 = 2016;\n        b.value2017 = 2017;\n        b.value2018 = 2018;\n        b.value2019 = 2019;\n        b.value2020 = 2020;\n        b.value2021 = 2021;\n        b.value2022 = 2022;\n        b.value2023 = 2023;\n        b.value2024 = 2024;\n        b.value2025 = 2025;\n        b.value2026 = 2026;\n        b.value2027 = 2027;\n        b.value2028 = 2028;\n        b.value2029 = 2029;\n        b.value2030 = 2030;\n        b.value2031 = 2031;\n        b.value2032 = 2032;\n        b.value2033 = 2033;\n        b.value2034 = 2034;\n        b.value2035 = 2035;\n        b.value2036 = 2036;\n        b.value2037 = 2037;\n        b.value2038 = 2038;\n        b.value2039 = 2039;\n        b.value2040 = 2040;\n        b.value2041 = 2041;\n        b.value2042 = 2042;\n        b.value2043 = 2043;\n        b.value2044 = 2044;\n        b.value2045 = 2045;\n        b.value2046 = 2046;\n        b.value2047 = 2047;\n        b.value2048 = 2048;\n        b.value2049 = 2049;\n        b.value2050 = 2050;\n        b.value2051 = 2051;\n        b.value2052 = 2052;\n        b.value2053 = 2053;\n        b.value2054 = 2054;\n        b.value2055 = 2055;\n        b.value2056 = 2056;\n        b.value2057 = 2057;\n        b.value2058 = 2058;\n        b.value2059 = 2059;\n        b.value2060 = 2060;\n        b.value2061 = 2061;\n        b.value2062 = 2062;\n        b.value2063 = 2063;\n        b.value2064 = 2064;\n        b.value2065 = 2065;\n        b.value2066 = 2066;\n        b.value2067 = 2067;\n        b.value2068 = 2068;\n        b.value2069 = 2069;\n        b.value2070 = 2070;\n        b.value2071 = 2071;\n        b.value2072 = 2072;\n        b.value2073 = 2073;\n        b.value2074 = 2074;\n        b.value2075 = 2075;\n        b.value2076 = 2076;\n        b.value2077 = 2077;\n        b.value2078 = 2078;\n        b.value2079 = 2079;\n        b.value2080 = 2080;\n        b.value2081 = 2081;\n        b.value2082 = 2082;\n        b.value2083 = 2083;\n        b.value2084 = 2084;\n        b.value2085 = 2085;\n        b.value2086 = 2086;\n        b.value2087 = 2087;\n        b.value2088 = 2088;\n        b.value2089 = 2089;\n        b.value2090 = 2090;\n        b.value2091 = 2091;\n        b.value2092 = 2092;\n        b.value2093 = 2093;\n        b.value2094 = 2094;\n        b.value2095 = 2095;\n        b.value2096 = 2096;\n        b.value2097 = 2097;\n        b.value2098 = 2098;\n        b.value2099 = 2099;\n        b.value2100 = 2100;\n        b.value2101 = 2101;\n        b.value2102 = 2102;\n        b.value2103 = 2103;\n        b.value2104 = 2104;\n        b.value2105 = 2105;\n        b.value2106 = 2106;\n        b.value2107 = 2107;\n        b.value2108 = 2108;\n        b.value2109 = 2109;\n        b.value2110 = 2110;\n        b.value2111 = 2111;\n        b.value2112 = 2112;\n        b.value2113 = 2113;\n        b.value2114 = 2114;\n        b.value2115 = 2115;\n        b.value2116 = 2116;\n        b.value2117 = 2117;\n        b.value2118 = 2118;\n        b.value2119 = 2119;\n        b.value2120 = 2120;\n        b.value2121 = 2121;\n        b.value2122 = 2122;\n        b.value2123 = 2123;\n        b.value2124 = 2124;\n        b.value2125 = 2125;\n        b.value2126 = 2126;\n        b.value2127 = 2127;\n        b.value2128 = 2128;\n        b.value2129 = 2129;\n        b.value2130 = 2130;\n        b.value2131 = 2131;\n        b.value2132 = 2132;\n        b.value2133 = 2133;\n        b.value2134 = 2134;\n        b.value2135 = 2135;\n        b.value2136 = 2136;\n        b.value2137 = 2137;\n        b.value2138 = 2138;\n        b.value2139 = 2139;\n        b.value2140 = 2140;\n        b.value2141 = 2141;\n        b.value2142 = 2142;\n        b.value2143 = 2143;\n        b.value2144 = 2144;\n        b.value2145 = 2145;\n        b.value2146 = 2146;\n        b.value2147 = 2147;\n        b.value2148 = 2148;\n        b.value2149 = 2149;\n        b.value2150 = 2150;\n        b.value2151 = 2151;\n        b.value2152 = 2152;\n        b.value2153 = 2153;\n        b.value2154 = 2154;\n        b.value2155 = 2155;\n        b.value2156 = 2156;\n        b.value2157 = 2157;\n        b.value2158 = 2158;\n        b.value2159 = 2159;\n        b.value2160 = 2160;\n        b.value2161 = 2161;\n        b.value2162 = 2162;\n        b.value2163 = 2163;\n        b.value2164 = 2164;\n        b.value2165 = 2165;\n        b.value2166 = 2166;\n        b.value2167 = 2167;\n        b.value2168 = 2168;\n        b.value2169 = 2169;\n        b.value2170 = 2170;\n        b.value2171 = 2171;\n        b.value2172 = 2172;\n        b.value2173 = 2173;\n        b.value2174 = 2174;\n        b.value2175 = 2175;\n        b.value2176 = 2176;\n        b.value2177 = 2177;\n        b.value2178 = 2178;\n        b.value2179 = 2179;\n        b.value2180 = 2180;\n        b.value2181 = 2181;\n        b.value2182 = 2182;\n        b.value2183 = 2183;\n        b.value2184 = 2184;\n        b.value2185 = 2185;\n        b.value2186 = 2186;\n        b.value2187 = 2187;\n        b.value2188 = 2188;\n        b.value2189 = 2189;\n        b.value2190 = 2190;\n        b.value2191 = 2191;\n        b.value2192 = 2192;\n        b.value2193 = 2193;\n        b.value2194 = 2194;\n        b.value2195 = 2195;\n        b.value2196 = 2196;\n        b.value2197 = 2197;\n        b.value2198 = 2198;\n        b.value2199 = 2199;\n        b.value2200 = 2200;\n        b.value2201 = 2201;\n        b.value2202 = 2202;\n        b.value2203 = 2203;\n        b.value2204 = 2204;\n        b.value2205 = 2205;\n        b.value2206 = 2206;\n        b.value2207 = 2207;\n        b.value2208 = 2208;\n        b.value2209 = 2209;\n        b.value2210 = 2210;\n        b.value2211 = 2211;\n        b.value2212 = 2212;\n        b.value2213 = 2213;\n        b.value2214 = 2214;\n        b.value2215 = 2215;\n        b.value2216 = 2216;\n        b.value2217 = 2217;\n        b.value2218 = 2218;\n        b.value2219 = 2219;\n        b.value2220 = 2220;\n        b.value2221 = 2221;\n        b.value2222 = 2222;\n        b.value2223 = 2223;\n        b.value2224 = 2224;\n        b.value2225 = 2225;\n        b.value2226 = 2226;\n        b.value2227 = 2227;\n        b.value2228 = 2228;\n        b.value2229 = 2229;\n        b.value2230 = 2230;\n        b.value2231 = 2231;\n        b.value2232 = 2232;\n        b.value2233 = 2233;\n        b.value2234 = 2234;\n        b.value2235 = 2235;\n        b.value2236 = 2236;\n        b.value2237 = 2237;\n        b.value2238 = 2238;\n        b.value2239 = 2239;\n        b.value2240 = 2240;\n        b.value2241 = 2241;\n        b.value2242 = 2242;\n        b.value2243 = 2243;\n        b.value2244 = 2244;\n        b.value2245 = 2245;\n        b.value2246 = 2246;\n        b.value2247 = 2247;\n        b.value2248 = 2248;\n        b.value2249 = 2249;\n        b.value2250 = 2250;\n        b.value2251 = 2251;\n        b.value2252 = 2252;\n        b.value2253 = 2253;\n        b.value2254 = 2254;\n        b.value2255 = 2255;\n        b.value2256 = 2256;\n        b.value2257 = 2257;\n        b.value2258 = 2258;\n        b.value2259 = 2259;\n        b.value2260 = 2260;\n        b.value2261 = 2261;\n        b.value2262 = 2262;\n        b.value2263 = 2263;\n        b.value2264 = 2264;\n        b.value2265 = 2265;\n        b.value2266 = 2266;\n        b.value2267 = 2267;\n        b.value2268 = 2268;\n        b.value2269 = 2269;\n        b.value2270 = 2270;\n        b.value2271 = 2271;\n        b.value2272 = 2272;\n        b.value2273 = 2273;\n        b.value2274 = 2274;\n        b.value2275 = 2275;\n        b.value2276 = 2276;\n        b.value2277 = 2277;\n        b.value2278 = 2278;\n        b.value2279 = 2279;\n        b.value2280 = 2280;\n        b.value2281 = 2281;\n        b.value2282 = 2282;\n        b.value2283 = 2283;\n        b.value2284 = 2284;\n        b.value2285 = 2285;\n        b.value2286 = 2286;\n        b.value2287 = 2287;\n        b.value2288 = 2288;\n        b.value2289 = 2289;\n        b.value2290 = 2290;\n        b.value2291 = 2291;\n        b.value2292 = 2292;\n        b.value2293 = 2293;\n        b.value2294 = 2294;\n        b.value2295 = 2295;\n        b.value2296 = 2296;\n        b.value2297 = 2297;\n        b.value2298 = 2298;\n        b.value2299 = 2299;\n        b.value2300 = 2300;\n        b.value2301 = 2301;\n        b.value2302 = 2302;\n        b.value2303 = 2303;\n        b.value2304 = 2304;\n        b.value2305 = 2305;\n        b.value2306 = 2306;\n        b.value2307 = 2307;\n        b.value2308 = 2308;\n        b.value2309 = 2309;\n        b.value2310 = 2310;\n        b.value2311 = 2311;\n        b.value2312 = 2312;\n        b.value2313 = 2313;\n        b.value2314 = 2314;\n        b.value2315 = 2315;\n        b.value2316 = 2316;\n        b.value2317 = 2317;\n        b.value2318 = 2318;\n        b.value2319 = 2319;\n        b.value2320 = 2320;\n        b.value2321 = 2321;\n        b.value2322 = 2322;\n        b.value2323 = 2323;\n        b.value2324 = 2324;\n        b.value2325 = 2325;\n        b.value2326 = 2326;\n        b.value2327 = 2327;\n        b.value2328 = 2328;\n        b.value2329 = 2329;\n        b.value2330 = 2330;\n        b.value2331 = 2331;\n        b.value2332 = 2332;\n        b.value2333 = 2333;\n        b.value2334 = 2334;\n        b.value2335 = 2335;\n        b.value2336 = 2336;\n        b.value2337 = 2337;\n        b.value2338 = 2338;\n        b.value2339 = 2339;\n        b.value2340 = 2340;\n        b.value2341 = 2341;\n        b.value2342 = 2342;\n        b.value2343 = 2343;\n        b.value2344 = 2344;\n        b.value2345 = 2345;\n        b.value2346 = 2346;\n        b.value2347 = 2347;\n        b.value2348 = 2348;\n        b.value2349 = 2349;\n        b.value2350 = 2350;\n        b.value2351 = 2351;\n        b.value2352 = 2352;\n        b.value2353 = 2353;\n        b.value2354 = 2354;\n        b.value2355 = 2355;\n        b.value2356 = 2356;\n        b.value2357 = 2357;\n        b.value2358 = 2358;\n        b.value2359 = 2359;\n        b.value2360 = 2360;\n        b.value2361 = 2361;\n        b.value2362 = 2362;\n        b.value2363 = 2363;\n        b.value2364 = 2364;\n        b.value2365 = 2365;\n        b.value2366 = 2366;\n        b.value2367 = 2367;\n        b.value2368 = 2368;\n        b.value2369 = 2369;\n        b.value2370 = 2370;\n        b.value2371 = 2371;\n        b.value2372 = 2372;\n        b.value2373 = 2373;\n        b.value2374 = 2374;\n        b.value2375 = 2375;\n        b.value2376 = 2376;\n        b.value2377 = 2377;\n        b.value2378 = 2378;\n        b.value2379 = 2379;\n        b.value2380 = 2380;\n        b.value2381 = 2381;\n        b.value2382 = 2382;\n        b.value2383 = 2383;\n        b.value2384 = 2384;\n        b.value2385 = 2385;\n        b.value2386 = 2386;\n        b.value2387 = 2387;\n        b.value2388 = 2388;\n        b.value2389 = 2389;\n        b.value2390 = 2390;\n        b.value2391 = 2391;\n        b.value2392 = 2392;\n        b.value2393 = 2393;\n        b.value2394 = 2394;\n        b.value2395 = 2395;\n        b.value2396 = 2396;\n        b.value2397 = 2397;\n        b.value2398 = 2398;\n        b.value2399 = 2399;\n        b.value2400 = 2400;\n        b.value2401 = 2401;\n        b.value2402 = 2402;\n        b.value2403 = 2403;\n        b.value2404 = 2404;\n        b.value2405 = 2405;\n        b.value2406 = 2406;\n        b.value2407 = 2407;\n        b.value2408 = 2408;\n        b.value2409 = 2409;\n        b.value2410 = 2410;\n        b.value2411 = 2411;\n        b.value2412 = 2412;\n        b.value2413 = 2413;\n        b.value2414 = 2414;\n        b.value2415 = 2415;\n        b.value2416 = 2416;\n        b.value2417 = 2417;\n        b.value2418 = 2418;\n        b.value2419 = 2419;\n        b.value2420 = 2420;\n        b.value2421 = 2421;\n        b.value2422 = 2422;\n        b.value2423 = 2423;\n        b.value2424 = 2424;\n        b.value2425 = 2425;\n        b.value2426 = 2426;\n        b.value2427 = 2427;\n        b.value2428 = 2428;\n        b.value2429 = 2429;\n        b.value2430 = 2430;\n        b.value2431 = 2431;\n        b.value2432 = 2432;\n        b.value2433 = 2433;\n        b.value2434 = 2434;\n        b.value2435 = 2435;\n        b.value2436 = 2436;\n        b.value2437 = 2437;\n        b.value2438 = 2438;\n        b.value2439 = 2439;\n        b.value2440 = 2440;\n        b.value2441 = 2441;\n        b.value2442 = 2442;\n        b.value2443 = 2443;\n        b.value2444 = 2444;\n        b.value2445 = 2445;\n        b.value2446 = 2446;\n        b.value2447 = 2447;\n        b.value2448 = 2448;\n        b.value2449 = 2449;\n        b.value2450 = 2450;\n        b.value2451 = 2451;\n        b.value2452 = 2452;\n        b.value2453 = 2453;\n        b.value2454 = 2454;\n        b.value2455 = 2455;\n        b.value2456 = 2456;\n        b.value2457 = 2457;\n        b.value2458 = 2458;\n        b.value2459 = 2459;\n        b.value2460 = 2460;\n        b.value2461 = 2461;\n        b.value2462 = 2462;\n        b.value2463 = 2463;\n        b.value2464 = 2464;\n        b.value2465 = 2465;\n        b.value2466 = 2466;\n        b.value2467 = 2467;\n        b.value2468 = 2468;\n        b.value2469 = 2469;\n        b.value2470 = 2470;\n        b.value2471 = 2471;\n        b.value2472 = 2472;\n        b.value2473 = 2473;\n        b.value2474 = 2474;\n        b.value2475 = 2475;\n        b.value2476 = 2476;\n        b.value2477 = 2477;\n        b.value2478 = 2478;\n        b.value2479 = 2479;\n        b.value2480 = 2480;\n        b.value2481 = 2481;\n        b.value2482 = 2482;\n        b.value2483 = 2483;\n        b.value2484 = 2484;\n        b.value2485 = 2485;\n        b.value2486 = 2486;\n        b.value2487 = 2487;\n        b.value2488 = 2488;\n        b.value2489 = 2489;\n        b.value2490 = 2490;\n        b.value2491 = 2491;\n        b.value2492 = 2492;\n        b.value2493 = 2493;\n        b.value2494 = 2494;\n        b.value2495 = 2495;\n        b.value2496 = 2496;\n        b.value2497 = 2497;\n        b.value2498 = 2498;\n        b.value2499 = 2499;\n        b.value2500 = 2500;\n        b.value2501 = 2501;\n        b.value2502 = 2502;\n        b.value2503 = 2503;\n        b.value2504 = 2504;\n        b.value2505 = 2505;\n        b.value2506 = 2506;\n        b.value2507 = 2507;\n        b.value2508 = 2508;\n        b.value2509 = 2509;\n        b.value2510 = 2510;\n        b.value2511 = 2511;\n        b.value2512 = 2512;\n        b.value2513 = 2513;\n        b.value2514 = 2514;\n        b.value2515 = 2515;\n        b.value2516 = 2516;\n        b.value2517 = 2517;\n        b.value2518 = 2518;\n        b.value2519 = 2519;\n        b.value2520 = 2520;\n        b.value2521 = 2521;\n        b.value2522 = 2522;\n        b.value2523 = 2523;\n        b.value2524 = 2524;\n        b.value2525 = 2525;\n        b.value2526 = 2526;\n        b.value2527 = 2527;\n        b.value2528 = 2528;\n        b.value2529 = 2529;\n        b.value2530 = 2530;\n        b.value2531 = 2531;\n        b.value2532 = 2532;\n        b.value2533 = 2533;\n        b.value2534 = 2534;\n        b.value2535 = 2535;\n        b.value2536 = 2536;\n        b.value2537 = 2537;\n        b.value2538 = 2538;\n        b.value2539 = 2539;\n        b.value2540 = 2540;\n        b.value2541 = 2541;\n        b.value2542 = 2542;\n        b.value2543 = 2543;\n        b.value2544 = 2544;\n        b.value2545 = 2545;\n        b.value2546 = 2546;\n        b.value2547 = 2547;\n        b.value2548 = 2548;\n        b.value2549 = 2549;\n        b.value2550 = 2550;\n        b.value2551 = 2551;\n        b.value2552 = 2552;\n        b.value2553 = 2553;\n        b.value2554 = 2554;\n        b.value2555 = 2555;\n        b.value2556 = 2556;\n        b.value2557 = 2557;\n        b.value2558 = 2558;\n        b.value2559 = 2559;\n        b.value2560 = 2560;\n        b.value2561 = 2561;\n        b.value2562 = 2562;\n        b.value2563 = 2563;\n        b.value2564 = 2564;\n        b.value2565 = 2565;\n        b.value2566 = 2566;\n        b.value2567 = 2567;\n        b.value2568 = 2568;\n        b.value2569 = 2569;\n        b.value2570 = 2570;\n        b.value2571 = 2571;\n        b.value2572 = 2572;\n        b.value2573 = 2573;\n        b.value2574 = 2574;\n        b.value2575 = 2575;\n        b.value2576 = 2576;\n        b.value2577 = 2577;\n        b.value2578 = 2578;\n        b.value2579 = 2579;\n        b.value2580 = 2580;\n        b.value2581 = 2581;\n        b.value2582 = 2582;\n        b.value2583 = 2583;\n        b.value2584 = 2584;\n        b.value2585 = 2585;\n        b.value2586 = 2586;\n        b.value2587 = 2587;\n        b.value2588 = 2588;\n        b.value2589 = 2589;\n        b.value2590 = 2590;\n        b.value2591 = 2591;\n        b.value2592 = 2592;\n        b.value2593 = 2593;\n        b.value2594 = 2594;\n        b.value2595 = 2595;\n        b.value2596 = 2596;\n        b.value2597 = 2597;\n        b.value2598 = 2598;\n        b.value2599 = 2599;\n        b.value2600 = 2600;\n        b.value2601 = 2601;\n        b.value2602 = 2602;\n        b.value2603 = 2603;\n        b.value2604 = 2604;\n        b.value2605 = 2605;\n        b.value2606 = 2606;\n        b.value2607 = 2607;\n        b.value2608 = 2608;\n        b.value2609 = 2609;\n        b.value2610 = 2610;\n        b.value2611 = 2611;\n        b.value2612 = 2612;\n        b.value2613 = 2613;\n        b.value2614 = 2614;\n        b.value2615 = 2615;\n        b.value2616 = 2616;\n        b.value2617 = 2617;\n        b.value2618 = 2618;\n        b.value2619 = 2619;\n        b.value2620 = 2620;\n        b.value2621 = 2621;\n        b.value2622 = 2622;\n        b.value2623 = 2623;\n        b.value2624 = 2624;\n        b.value2625 = 2625;\n        b.value2626 = 2626;\n        b.value2627 = 2627;\n        b.value2628 = 2628;\n        b.value2629 = 2629;\n        b.value2630 = 2630;\n        b.value2631 = 2631;\n        b.value2632 = 2632;\n        b.value2633 = 2633;\n        b.value2634 = 2634;\n        b.value2635 = 2635;\n        b.value2636 = 2636;\n        b.value2637 = 2637;\n        b.value2638 = 2638;\n        b.value2639 = 2639;\n        b.value2640 = 2640;\n        b.value2641 = 2641;\n        b.value2642 = 2642;\n        b.value2643 = 2643;\n        b.value2644 = 2644;\n        b.value2645 = 2645;\n        b.value2646 = 2646;\n        b.value2647 = 2647;\n        b.value2648 = 2648;\n        b.value2649 = 2649;\n        b.value2650 = 2650;\n        b.value2651 = 2651;\n        b.value2652 = 2652;\n        b.value2653 = 2653;\n        b.value2654 = 2654;\n        b.value2655 = 2655;\n        b.value2656 = 2656;\n        b.value2657 = 2657;\n        b.value2658 = 2658;\n        b.value2659 = 2659;\n        b.value2660 = 2660;\n        b.value2661 = 2661;\n        b.value2662 = 2662;\n        b.value2663 = 2663;\n        b.value2664 = 2664;\n        b.value2665 = 2665;\n        b.value2666 = 2666;\n        b.value2667 = 2667;\n        b.value2668 = 2668;\n        b.value2669 = 2669;\n        b.value2670 = 2670;\n        b.value2671 = 2671;\n        b.value2672 = 2672;\n        b.value2673 = 2673;\n        b.value2674 = 2674;\n        b.value2675 = 2675;\n        b.value2676 = 2676;\n        b.value2677 = 2677;\n        b.value2678 = 2678;\n        b.value2679 = 2679;\n        b.value2680 = 2680;\n        b.value2681 = 2681;\n        b.value2682 = 2682;\n        b.value2683 = 2683;\n        b.value2684 = 2684;\n        b.value2685 = 2685;\n        b.value2686 = 2686;\n        b.value2687 = 2687;\n        b.value2688 = 2688;\n        b.value2689 = 2689;\n        b.value2690 = 2690;\n        b.value2691 = 2691;\n        b.value2692 = 2692;\n        b.value2693 = 2693;\n        b.value2694 = 2694;\n        b.value2695 = 2695;\n        b.value2696 = 2696;\n        b.value2697 = 2697;\n        b.value2698 = 2698;\n        b.value2699 = 2699;\n        b.value2700 = 2700;\n        b.value2701 = 2701;\n        b.value2702 = 2702;\n        b.value2703 = 2703;\n        b.value2704 = 2704;\n        b.value2705 = 2705;\n        b.value2706 = 2706;\n        b.value2707 = 2707;\n        b.value2708 = 2708;\n        b.value2709 = 2709;\n        b.value2710 = 2710;\n        b.value2711 = 2711;\n        b.value2712 = 2712;\n        b.value2713 = 2713;\n        b.value2714 = 2714;\n        b.value2715 = 2715;\n        b.value2716 = 2716;\n        b.value2717 = 2717;\n        b.value2718 = 2718;\n        b.value2719 = 2719;\n        b.value2720 = 2720;\n        b.value2721 = 2721;\n        b.value2722 = 2722;\n        b.value2723 = 2723;\n        b.value2724 = 2724;\n        b.value2725 = 2725;\n        b.value2726 = 2726;\n        b.value2727 = 2727;\n        b.value2728 = 2728;\n        b.value2729 = 2729;\n        b.value2730 = 2730;\n        b.value2731 = 2731;\n        b.value2732 = 2732;\n        b.value2733 = 2733;\n        b.value2734 = 2734;\n        b.value2735 = 2735;\n        b.value2736 = 2736;\n        b.value2737 = 2737;\n        b.value2738 = 2738;\n        b.value2739 = 2739;\n        b.value2740 = 2740;\n        b.value2741 = 2741;\n        b.value2742 = 2742;\n        b.value2743 = 2743;\n        b.value2744 = 2744;\n        b.value2745 = 2745;\n        b.value2746 = 2746;\n        b.value2747 = 2747;\n        b.value2748 = 2748;\n        b.value2749 = 2749;\n        b.value2750 = 2750;\n        b.value2751 = 2751;\n        b.value2752 = 2752;\n        b.value2753 = 2753;\n        b.value2754 = 2754;\n        b.value2755 = 2755;\n        b.value2756 = 2756;\n        b.value2757 = 2757;\n        b.value2758 = 2758;\n        b.value2759 = 2759;\n        b.value2760 = 2760;\n        b.value2761 = 2761;\n        b.value2762 = 2762;\n        b.value2763 = 2763;\n        b.value2764 = 2764;\n        b.value2765 = 2765;\n        b.value2766 = 2766;\n        b.value2767 = 2767;\n        b.value2768 = 2768;\n        b.value2769 = 2769;\n        b.value2770 = 2770;\n        b.value2771 = 2771;\n        b.value2772 = 2772;\n        b.value2773 = 2773;\n        b.value2774 = 2774;\n        b.value2775 = 2775;\n        b.value2776 = 2776;\n        b.value2777 = 2777;\n        b.value2778 = 2778;\n        b.value2779 = 2779;\n        b.value2780 = 2780;\n        b.value2781 = 2781;\n        b.value2782 = 2782;\n        b.value2783 = 2783;\n        b.value2784 = 2784;\n        b.value2785 = 2785;\n        b.value2786 = 2786;\n        b.value2787 = 2787;\n        b.value2788 = 2788;\n        b.value2789 = 2789;\n        b.value2790 = 2790;\n        b.value2791 = 2791;\n        b.value2792 = 2792;\n        b.value2793 = 2793;\n        b.value2794 = 2794;\n        b.value2795 = 2795;\n        b.value2796 = 2796;\n        b.value2797 = 2797;\n        b.value2798 = 2798;\n        b.value2799 = 2799;\n        b.value2800 = 2800;\n        b.value2801 = 2801;\n        b.value2802 = 2802;\n        b.value2803 = 2803;\n        b.value2804 = 2804;\n        b.value2805 = 2805;\n        b.value2806 = 2806;\n        b.value2807 = 2807;\n        b.value2808 = 2808;\n        b.value2809 = 2809;\n        b.value2810 = 2810;\n        b.value2811 = 2811;\n        b.value2812 = 2812;\n        b.value2813 = 2813;\n        b.value2814 = 2814;\n        b.value2815 = 2815;\n        b.value2816 = 2816;\n        b.value2817 = 2817;\n        b.value2818 = 2818;\n        b.value2819 = 2819;\n        b.value2820 = 2820;\n        b.value2821 = 2821;\n        b.value2822 = 2822;\n        b.value2823 = 2823;\n        b.value2824 = 2824;\n        b.value2825 = 2825;\n        b.value2826 = 2826;\n        b.value2827 = 2827;\n        b.value2828 = 2828;\n        b.value2829 = 2829;\n        b.value2830 = 2830;\n        b.value2831 = 2831;\n        b.value2832 = 2832;\n        b.value2833 = 2833;\n        b.value2834 = 2834;\n        b.value2835 = 2835;\n        b.value2836 = 2836;\n        b.value2837 = 2837;\n        b.value2838 = 2838;\n        b.value2839 = 2839;\n        b.value2840 = 2840;\n        b.value2841 = 2841;\n        b.value2842 = 2842;\n        b.value2843 = 2843;\n        b.value2844 = 2844;\n        b.value2845 = 2845;\n        b.value2846 = 2846;\n        b.value2847 = 2847;\n        b.value2848 = 2848;\n        b.value2849 = 2849;\n        b.value2850 = 2850;\n        b.value2851 = 2851;\n        b.value2852 = 2852;\n        b.value2853 = 2853;\n        b.value2854 = 2854;\n        b.value2855 = 2855;\n        b.value2856 = 2856;\n        b.value2857 = 2857;\n        b.value2858 = 2858;\n        b.value2859 = 2859;\n        b.value2860 = 2860;\n        b.value2861 = 2861;\n        b.value2862 = 2862;\n        b.value2863 = 2863;\n        b.value2864 = 2864;\n        b.value2865 = 2865;\n        b.value2866 = 2866;\n        b.value2867 = 2867;\n        b.value2868 = 2868;\n        b.value2869 = 2869;\n        b.value2870 = 2870;\n        b.value2871 = 2871;\n        b.value2872 = 2872;\n        b.value2873 = 2873;\n        b.value2874 = 2874;\n        b.value2875 = 2875;\n        b.value2876 = 2876;\n        b.value2877 = 2877;\n        b.value2878 = 2878;\n        b.value2879 = 2879;\n        b.value2880 = 2880;\n        b.value2881 = 2881;\n        b.value2882 = 2882;\n        b.value2883 = 2883;\n        b.value2884 = 2884;\n        b.value2885 = 2885;\n        b.value2886 = 2886;\n        b.value2887 = 2887;\n        b.value2888 = 2888;\n        b.value2889 = 2889;\n        b.value2890 = 2890;\n        b.value2891 = 2891;\n        b.value2892 = 2892;\n        b.value2893 = 2893;\n        b.value2894 = 2894;\n        b.value2895 = 2895;\n        b.value2896 = 2896;\n        b.value2897 = 2897;\n        b.value2898 = 2898;\n        b.value2899 = 2899;\n        b.value2900 = 2900;\n        b.value2901 = 2901;\n        b.value2902 = 2902;\n        b.value2903 = 2903;\n        b.value2904 = 2904;\n        b.value2905 = 2905;\n        b.value2906 = 2906;\n        b.value2907 = 2907;\n        b.value2908 = 2908;\n        b.value2909 = 2909;\n        b.value2910 = 2910;\n        b.value2911 = 2911;\n        b.value2912 = 2912;\n        b.value2913 = 2913;\n        b.value2914 = 2914;\n        b.value2915 = 2915;\n        b.value2916 = 2916;\n        b.value2917 = 2917;\n        b.value2918 = 2918;\n        b.value2919 = 2919;\n        b.value2920 = 2920;\n        b.value2921 = 2921;\n        b.value2922 = 2922;\n        b.value2923 = 2923;\n        b.value2924 = 2924;\n        b.value2925 = 2925;\n        b.value2926 = 2926;\n        b.value2927 = 2927;\n        b.value2928 = 2928;\n        b.value2929 = 2929;\n        b.value2930 = 2930;\n        b.value2931 = 2931;\n        b.value2932 = 2932;\n        b.value2933 = 2933;\n        b.value2934 = 2934;\n        b.value2935 = 2935;\n        b.value2936 = 2936;\n        b.value2937 = 2937;\n        b.value2938 = 2938;\n        b.value2939 = 2939;\n        b.value2940 = 2940;\n        b.value2941 = 2941;\n        b.value2942 = 2942;\n        b.value2943 = 2943;\n        b.value2944 = 2944;\n        b.value2945 = 2945;\n        b.value2946 = 2946;\n        b.value2947 = 2947;\n        b.value2948 = 2948;\n        b.value2949 = 2949;\n        b.value2950 = 2950;\n        b.value2951 = 2951;\n        b.value2952 = 2952;\n        b.value2953 = 2953;\n        b.value2954 = 2954;\n        b.value2955 = 2955;\n        b.value2956 = 2956;\n        b.value2957 = 2957;\n        b.value2958 = 2958;\n        b.value2959 = 2959;\n        b.value2960 = 2960;\n        b.value2961 = 2961;\n        b.value2962 = 2962;\n        b.value2963 = 2963;\n        b.value2964 = 2964;\n        b.value2965 = 2965;\n        b.value2966 = 2966;\n        b.value2967 = 2967;\n        b.value2968 = 2968;\n        b.value2969 = 2969;\n        b.value2970 = 2970;\n        b.value2971 = 2971;\n        b.value2972 = 2972;\n        b.value2973 = 2973;\n        b.value2974 = 2974;\n        b.value2975 = 2975;\n        b.value2976 = 2976;\n        b.value2977 = 2977;\n        b.value2978 = 2978;\n        b.value2979 = 2979;\n        b.value2980 = 2980;\n        b.value2981 = 2981;\n        b.value2982 = 2982;\n        b.value2983 = 2983;\n        b.value2984 = 2984;\n        b.value2985 = 2985;\n        b.value2986 = 2986;\n        b.value2987 = 2987;\n        b.value2988 = 2988;\n        b.value2989 = 2989;\n        b.value2990 = 2990;\n        b.value2991 = 2991;\n        b.value2992 = 2992;\n        b.value2993 = 2993;\n        b.value2994 = 2994;\n        b.value2995 = 2995;\n        b.value2996 = 2996;\n        b.value2997 = 2997;\n        b.value2998 = 2998;\n        b.value2999 = 2999;\n        b.value3000 = 3000;\n        b.value3001 = 3001;\n        b.value3002 = 3002;\n        b.value3003 = 3003;\n        b.value3004 = 3004;\n        b.value3005 = 3005;\n        b.value3006 = 3006;\n        b.value3007 = 3007;\n        b.value3008 = 3008;\n        b.value3009 = 3009;\n        b.value3010 = 3010;\n        b.value3011 = 3011;\n        b.value3012 = 3012;\n        b.value3013 = 3013;\n        b.value3014 = 3014;\n        b.value3015 = 3015;\n        b.value3016 = 3016;\n        b.value3017 = 3017;\n        b.value3018 = 3018;\n        b.value3019 = 3019;\n        b.value3020 = 3020;\n        b.value3021 = 3021;\n        b.value3022 = 3022;\n        b.value3023 = 3023;\n        b.value3024 = 3024;\n        b.value3025 = 3025;\n        b.value3026 = 3026;\n        b.value3027 = 3027;\n        b.value3028 = 3028;\n        b.value3029 = 3029;\n        b.value3030 = 3030;\n        b.value3031 = 3031;\n        b.value3032 = 3032;\n        b.value3033 = 3033;\n        b.value3034 = 3034;\n        b.value3035 = 3035;\n        b.value3036 = 3036;\n        b.value3037 = 3037;\n        b.value3038 = 3038;\n        b.value3039 = 3039;\n        b.value3040 = 3040;\n        b.value3041 = 3041;\n        b.value3042 = 3042;\n        b.value3043 = 3043;\n        b.value3044 = 3044;\n        b.value3045 = 3045;\n        b.value3046 = 3046;\n        b.value3047 = 3047;\n        b.value3048 = 3048;\n        b.value3049 = 3049;\n        b.value3050 = 3050;\n        b.value3051 = 3051;\n        b.value3052 = 3052;\n        b.value3053 = 3053;\n        b.value3054 = 3054;\n        b.value3055 = 3055;\n        b.value3056 = 3056;\n        b.value3057 = 3057;\n        b.value3058 = 3058;\n        b.value3059 = 3059;\n        b.value3060 = 3060;\n        b.value3061 = 3061;\n        b.value3062 = 3062;\n        b.value3063 = 3063;\n        b.value3064 = 3064;\n        b.value3065 = 3065;\n        b.value3066 = 3066;\n        b.value3067 = 3067;\n        b.value3068 = 3068;\n        b.value3069 = 3069;\n        b.value3070 = 3070;\n        b.value3071 = 3071;\n        b.value3072 = 3072;\n        b.value3073 = 3073;\n        b.value3074 = 3074;\n        b.value3075 = 3075;\n        b.value3076 = 3076;\n        b.value3077 = 3077;\n        b.value3078 = 3078;\n        b.value3079 = 3079;\n        b.value3080 = 3080;\n        b.value3081 = 3081;\n        b.value3082 = 3082;\n        b.value3083 = 3083;\n        b.value3084 = 3084;\n        b.value3085 = 3085;\n        b.value3086 = 3086;\n        b.value3087 = 3087;\n        b.value3088 = 3088;\n        b.value3089 = 3089;\n        b.value3090 = 3090;\n        b.value3091 = 3091;\n        b.value3092 = 3092;\n        b.value3093 = 3093;\n        b.value3094 = 3094;\n        b.value3095 = 3095;\n        b.value3096 = 3096;\n        b.value3097 = 3097;\n        b.value3098 = 3098;\n        b.value3099 = 3099;\n        b.value3100 = 3100;\n        b.value3101 = 3101;\n        b.value3102 = 3102;\n        b.value3103 = 3103;\n        b.value3104 = 3104;\n        b.value3105 = 3105;\n        b.value3106 = 3106;\n        b.value3107 = 3107;\n        b.value3108 = 3108;\n        b.value3109 = 3109;\n        b.value3110 = 3110;\n        b.value3111 = 3111;\n        b.value3112 = 3112;\n        b.value3113 = 3113;\n        b.value3114 = 3114;\n        b.value3115 = 3115;\n        b.value3116 = 3116;\n        b.value3117 = 3117;\n        b.value3118 = 3118;\n        b.value3119 = 3119;\n        b.value3120 = 3120;\n        b.value3121 = 3121;\n        b.value3122 = 3122;\n        b.value3123 = 3123;\n        b.value3124 = 3124;\n        b.value3125 = 3125;\n        b.value3126 = 3126;\n        b.value3127 = 3127;\n        b.value3128 = 3128;\n        b.value3129 = 3129;\n        b.value3130 = 3130;\n        b.value3131 = 3131;\n        b.value3132 = 3132;\n        b.value3133 = 3133;\n        b.value3134 = 3134;\n        b.value3135 = 3135;\n        b.value3136 = 3136;\n        b.value3137 = 3137;\n        b.value3138 = 3138;\n        b.value3139 = 3139;\n        b.value3140 = 3140;\n        b.value3141 = 3141;\n        b.value3142 = 3142;\n        b.value3143 = 3143;\n        b.value3144 = 3144;\n        b.value3145 = 3145;\n        b.value3146 = 3146;\n        b.value3147 = 3147;\n        b.value3148 = 3148;\n        b.value3149 = 3149;\n        b.value3150 = 3150;\n        b.value3151 = 3151;\n        b.value3152 = 3152;\n        b.value3153 = 3153;\n        b.value3154 = 3154;\n        b.value3155 = 3155;\n        b.value3156 = 3156;\n        b.value3157 = 3157;\n        b.value3158 = 3158;\n        b.value3159 = 3159;\n        b.value3160 = 3160;\n        b.value3161 = 3161;\n        b.value3162 = 3162;\n        b.value3163 = 3163;\n        b.value3164 = 3164;\n        b.value3165 = 3165;\n        b.value3166 = 3166;\n        b.value3167 = 3167;\n        b.value3168 = 3168;\n        b.value3169 = 3169;\n        b.value3170 = 3170;\n        b.value3171 = 3171;\n        b.value3172 = 3172;\n        b.value3173 = 3173;\n        b.value3174 = 3174;\n        b.value3175 = 3175;\n        b.value3176 = 3176;\n        b.value3177 = 3177;\n        b.value3178 = 3178;\n        b.value3179 = 3179;\n        b.value3180 = 3180;\n        b.value3181 = 3181;\n        b.value3182 = 3182;\n        b.value3183 = 3183;\n        b.value3184 = 3184;\n        b.value3185 = 3185;\n        b.value3186 = 3186;\n        b.value3187 = 3187;\n        b.value3188 = 3188;\n        b.value3189 = 3189;\n        b.value3190 = 3190;\n        b.value3191 = 3191;\n        b.value3192 = 3192;\n        b.value3193 = 3193;\n        b.value3194 = 3194;\n        b.value3195 = 3195;\n        b.value3196 = 3196;\n        b.value3197 = 3197;\n        b.value3198 = 3198;\n        b.value3199 = 3199;\n        b.value3200 = 3200;\n        b.value3201 = 3201;\n        b.value3202 = 3202;\n        b.value3203 = 3203;\n        b.value3204 = 3204;\n        b.value3205 = 3205;\n        b.value3206 = 3206;\n        b.value3207 = 3207;\n        b.value3208 = 3208;\n        b.value3209 = 3209;\n        b.value3210 = 3210;\n        b.value3211 = 3211;\n        b.value3212 = 3212;\n        b.value3213 = 3213;\n        b.value3214 = 3214;\n        b.value3215 = 3215;\n        b.value3216 = 3216;\n        b.value3217 = 3217;\n        b.value3218 = 3218;\n        b.value3219 = 3219;\n        b.value3220 = 3220;\n        b.value3221 = 3221;\n        b.value3222 = 3222;\n        b.value3223 = 3223;\n        b.value3224 = 3224;\n        b.value3225 = 3225;\n        b.value3226 = 3226;\n        b.value3227 = 3227;\n        b.value3228 = 3228;\n        b.value3229 = 3229;\n        b.value3230 = 3230;\n        b.value3231 = 3231;\n        b.value3232 = 3232;\n        b.value3233 = 3233;\n        b.value3234 = 3234;\n        b.value3235 = 3235;\n        b.value3236 = 3236;\n        b.value3237 = 3237;\n        b.value3238 = 3238;\n        b.value3239 = 3239;\n        b.value3240 = 3240;\n        b.value3241 = 3241;\n        b.value3242 = 3242;\n        b.value3243 = 3243;\n        b.value3244 = 3244;\n        b.value3245 = 3245;\n        b.value3246 = 3246;\n        b.value3247 = 3247;\n        b.value3248 = 3248;\n        b.value3249 = 3249;\n        b.value3250 = 3250;\n        b.value3251 = 3251;\n        b.value3252 = 3252;\n        b.value3253 = 3253;\n        b.value3254 = 3254;\n        b.value3255 = 3255;\n        b.value3256 = 3256;\n        b.value3257 = 3257;\n        b.value3258 = 3258;\n        b.value3259 = 3259;\n        b.value3260 = 3260;\n        b.value3261 = 3261;\n        b.value3262 = 3262;\n        b.value3263 = 3263;\n        b.value3264 = 3264;\n        b.value3265 = 3265;\n        b.value3266 = 3266;\n        b.value3267 = 3267;\n        b.value3268 = 3268;\n        b.value3269 = 3269;\n        b.value3270 = 3270;\n        b.value3271 = 3271;\n        b.value3272 = 3272;\n        b.value3273 = 3273;\n        b.value3274 = 3274;\n        b.value3275 = 3275;\n        b.value3276 = 3276;\n        b.value3277 = 3277;\n        b.value3278 = 3278;\n        b.value3279 = 3279;\n        b.value3280 = 3280;\n        b.value3281 = 3281;\n        b.value3282 = 3282;\n        b.value3283 = 3283;\n        b.value3284 = 3284;\n        b.value3285 = 3285;\n        b.value3286 = 3286;\n        b.value3287 = 3287;\n        b.value3288 = 3288;\n        b.value3289 = 3289;\n        b.value3290 = 3290;\n        b.value3291 = 3291;\n        b.value3292 = 3292;\n        b.value3293 = 3293;\n        b.value3294 = 3294;\n        b.value3295 = 3295;\n        b.value3296 = 3296;\n        b.value3297 = 3297;\n        b.value3298 = 3298;\n        b.value3299 = 3299;\n        b.value3300 = 3300;\n        b.value3301 = 3301;\n        b.value3302 = 3302;\n        b.value3303 = 3303;\n        b.value3304 = 3304;\n        b.value3305 = 3305;\n        b.value3306 = 3306;\n        b.value3307 = 3307;\n        b.value3308 = 3308;\n        b.value3309 = 3309;\n        b.value3310 = 3310;\n        b.value3311 = 3311;\n        b.value3312 = 3312;\n        b.value3313 = 3313;\n        b.value3314 = 3314;\n        b.value3315 = 3315;\n        b.value3316 = 3316;\n        b.value3317 = 3317;\n        b.value3318 = 3318;\n        b.value3319 = 3319;\n        b.value3320 = 3320;\n        b.value3321 = 3321;\n        b.value3322 = 3322;\n        b.value3323 = 3323;\n        b.value3324 = 3324;\n        b.value3325 = 3325;\n        b.value3326 = 3326;\n        b.value3327 = 3327;\n        b.value3328 = 3328;\n        b.value3329 = 3329;\n        b.value3330 = 3330;\n        b.value3331 = 3331;\n        b.value3332 = 3332;\n        b.value3333 = 3333;\n        b.value3334 = 3334;\n        b.value3335 = 3335;\n        b.value3336 = 3336;\n        b.value3337 = 3337;\n        b.value3338 = 3338;\n        b.value3339 = 3339;\n        b.value3340 = 3340;\n        b.value3341 = 3341;\n        b.value3342 = 3342;\n        b.value3343 = 3343;\n        b.value3344 = 3344;\n        b.value3345 = 3345;\n        b.value3346 = 3346;\n        b.value3347 = 3347;\n        b.value3348 = 3348;\n        b.value3349 = 3349;\n        b.value3350 = 3350;\n        b.value3351 = 3351;\n        b.value3352 = 3352;\n        b.value3353 = 3353;\n        b.value3354 = 3354;\n        b.value3355 = 3355;\n        b.value3356 = 3356;\n        b.value3357 = 3357;\n        b.value3358 = 3358;\n        b.value3359 = 3359;\n        b.value3360 = 3360;\n        b.value3361 = 3361;\n        b.value3362 = 3362;\n        b.value3363 = 3363;\n        b.value3364 = 3364;\n        b.value3365 = 3365;\n        b.value3366 = 3366;\n        b.value3367 = 3367;\n        b.value3368 = 3368;\n        b.value3369 = 3369;\n        b.value3370 = 3370;\n        b.value3371 = 3371;\n        b.value3372 = 3372;\n        b.value3373 = 3373;\n        b.value3374 = 3374;\n        b.value3375 = 3375;\n        b.value3376 = 3376;\n        b.value3377 = 3377;\n        b.value3378 = 3378;\n        b.value3379 = 3379;\n        b.value3380 = 3380;\n        b.value3381 = 3381;\n        b.value3382 = 3382;\n        b.value3383 = 3383;\n        b.value3384 = 3384;\n        b.value3385 = 3385;\n        b.value3386 = 3386;\n        b.value3387 = 3387;\n        b.value3388 = 3388;\n        b.value3389 = 3389;\n        b.value3390 = 3390;\n        b.value3391 = 3391;\n        b.value3392 = 3392;\n        b.value3393 = 3393;\n        b.value3394 = 3394;\n        b.value3395 = 3395;\n        b.value3396 = 3396;\n        b.value3397 = 3397;\n        b.value3398 = 3398;\n        b.value3399 = 3399;\n        b.value3400 = 3400;\n        b.value3401 = 3401;\n        b.value3402 = 3402;\n        b.value3403 = 3403;\n        b.value3404 = 3404;\n        b.value3405 = 3405;\n        b.value3406 = 3406;\n        b.value3407 = 3407;\n        b.value3408 = 3408;\n        b.value3409 = 3409;\n        b.value3410 = 3410;\n        b.value3411 = 3411;\n        b.value3412 = 3412;\n        b.value3413 = 3413;\n        b.value3414 = 3414;\n        b.value3415 = 3415;\n        b.value3416 = 3416;\n        b.value3417 = 3417;\n        b.value3418 = 3418;\n        b.value3419 = 3419;\n        b.value3420 = 3420;\n        b.value3421 = 3421;\n        b.value3422 = 3422;\n        b.value3423 = 3423;\n        b.value3424 = 3424;\n        b.value3425 = 3425;\n        b.value3426 = 3426;\n        b.value3427 = 3427;\n        b.value3428 = 3428;\n        b.value3429 = 3429;\n        b.value3430 = 3430;\n        b.value3431 = 3431;\n        b.value3432 = 3432;\n        b.value3433 = 3433;\n        b.value3434 = 3434;\n        b.value3435 = 3435;\n        b.value3436 = 3436;\n        b.value3437 = 3437;\n        b.value3438 = 3438;\n        b.value3439 = 3439;\n        b.value3440 = 3440;\n        b.value3441 = 3441;\n        b.value3442 = 3442;\n        b.value3443 = 3443;\n        b.value3444 = 3444;\n        b.value3445 = 3445;\n        b.value3446 = 3446;\n        b.value3447 = 3447;\n        b.value3448 = 3448;\n        b.value3449 = 3449;\n        b.value3450 = 3450;\n        b.value3451 = 3451;\n        b.value3452 = 3452;\n        b.value3453 = 3453;\n        b.value3454 = 3454;\n        b.value3455 = 3455;\n        b.value3456 = 3456;\n        b.value3457 = 3457;\n        b.value3458 = 3458;\n        b.value3459 = 3459;\n        b.value3460 = 3460;\n        b.value3461 = 3461;\n        b.value3462 = 3462;\n        b.value3463 = 3463;\n        b.value3464 = 3464;\n        b.value3465 = 3465;\n        b.value3466 = 3466;\n        b.value3467 = 3467;\n        b.value3468 = 3468;\n        b.value3469 = 3469;\n        b.value3470 = 3470;\n        b.value3471 = 3471;\n        b.value3472 = 3472;\n        b.value3473 = 3473;\n        b.value3474 = 3474;\n        b.value3475 = 3475;\n        b.value3476 = 3476;\n        b.value3477 = 3477;\n        b.value3478 = 3478;\n        b.value3479 = 3479;\n        b.value3480 = 3480;\n        b.value3481 = 3481;\n        b.value3482 = 3482;\n        b.value3483 = 3483;\n        b.value3484 = 3484;\n        b.value3485 = 3485;\n        b.value3486 = 3486;\n        b.value3487 = 3487;\n        b.value3488 = 3488;\n        b.value3489 = 3489;\n        b.value3490 = 3490;\n        b.value3491 = 3491;\n        b.value3492 = 3492;\n        b.value3493 = 3493;\n        b.value3494 = 3494;\n        b.value3495 = 3495;\n        b.value3496 = 3496;\n        b.value3497 = 3497;\n        b.value3498 = 3498;\n        b.value3499 = 3499;\n        b.value3500 = 3500;\n        b.value3501 = 3501;\n        b.value3502 = 3502;\n        b.value3503 = 3503;\n        b.value3504 = 3504;\n        b.value3505 = 3505;\n        b.value3506 = 3506;\n        b.value3507 = 3507;\n        b.value3508 = 3508;\n        b.value3509 = 3509;\n        b.value3510 = 3510;\n        b.value3511 = 3511;\n        b.value3512 = 3512;\n        b.value3513 = 3513;\n        b.value3514 = 3514;\n        b.value3515 = 3515;\n        b.value3516 = 3516;\n        b.value3517 = 3517;\n        b.value3518 = 3518;\n        b.value3519 = 3519;\n        b.value3520 = 3520;\n        b.value3521 = 3521;\n        b.value3522 = 3522;\n        b.value3523 = 3523;\n        b.value3524 = 3524;\n        b.value3525 = 3525;\n        b.value3526 = 3526;\n        b.value3527 = 3527;\n        b.value3528 = 3528;\n        b.value3529 = 3529;\n        b.value3530 = 3530;\n        b.value3531 = 3531;\n        b.value3532 = 3532;\n        b.value3533 = 3533;\n        b.value3534 = 3534;\n        b.value3535 = 3535;\n        b.value3536 = 3536;\n        b.value3537 = 3537;\n        b.value3538 = 3538;\n        b.value3539 = 3539;\n        b.value3540 = 3540;\n        b.value3541 = 3541;\n        b.value3542 = 3542;\n        b.value3543 = 3543;\n        b.value3544 = 3544;\n        b.value3545 = 3545;\n        b.value3546 = 3546;\n        b.value3547 = 3547;\n        b.value3548 = 3548;\n        b.value3549 = 3549;\n        b.value3550 = 3550;\n        b.value3551 = 3551;\n        b.value3552 = 3552;\n        b.value3553 = 3553;\n        b.value3554 = 3554;\n        b.value3555 = 3555;\n        b.value3556 = 3556;\n        b.value3557 = 3557;\n        b.value3558 = 3558;\n        b.value3559 = 3559;\n        b.value3560 = 3560;\n        b.value3561 = 3561;\n        b.value3562 = 3562;\n        b.value3563 = 3563;\n        b.value3564 = 3564;\n        b.value3565 = 3565;\n        b.value3566 = 3566;\n        b.value3567 = 3567;\n        b.value3568 = 3568;\n        b.value3569 = 3569;\n        b.value3570 = 3570;\n        b.value3571 = 3571;\n        b.value3572 = 3572;\n        b.value3573 = 3573;\n        b.value3574 = 3574;\n        b.value3575 = 3575;\n        b.value3576 = 3576;\n        b.value3577 = 3577;\n        b.value3578 = 3578;\n        b.value3579 = 3579;\n        b.value3580 = 3580;\n        b.value3581 = 3581;\n        b.value3582 = 3582;\n        b.value3583 = 3583;\n        b.value3584 = 3584;\n        b.value3585 = 3585;\n        b.value3586 = 3586;\n        b.value3587 = 3587;\n        b.value3588 = 3588;\n        b.value3589 = 3589;\n        b.value3590 = 3590;\n        b.value3591 = 3591;\n        b.value3592 = 3592;\n        b.value3593 = 3593;\n        b.value3594 = 3594;\n        b.value3595 = 3595;\n        b.value3596 = 3596;\n        b.value3597 = 3597;\n        b.value3598 = 3598;\n        b.value3599 = 3599;\n        b.value3600 = 3600;\n        b.value3601 = 3601;\n        b.value3602 = 3602;\n        b.value3603 = 3603;\n        b.value3604 = 3604;\n        b.value3605 = 3605;\n        b.value3606 = 3606;\n        b.value3607 = 3607;\n        b.value3608 = 3608;\n        b.value3609 = 3609;\n        b.value3610 = 3610;\n        b.value3611 = 3611;\n        b.value3612 = 3612;\n        b.value3613 = 3613;\n        b.value3614 = 3614;\n        b.value3615 = 3615;\n        b.value3616 = 3616;\n        b.value3617 = 3617;\n        b.value3618 = 3618;\n        b.value3619 = 3619;\n        b.value3620 = 3620;\n        b.value3621 = 3621;\n        b.value3622 = 3622;\n        b.value3623 = 3623;\n        b.value3624 = 3624;\n        b.value3625 = 3625;\n        b.value3626 = 3626;\n        b.value3627 = 3627;\n        b.value3628 = 3628;\n        b.value3629 = 3629;\n        b.value3630 = 3630;\n        b.value3631 = 3631;\n        b.value3632 = 3632;\n        b.value3633 = 3633;\n        b.value3634 = 3634;\n        b.value3635 = 3635;\n        b.value3636 = 3636;\n        b.value3637 = 3637;\n        b.value3638 = 3638;\n        b.value3639 = 3639;\n        b.value3640 = 3640;\n        b.value3641 = 3641;\n        b.value3642 = 3642;\n        b.value3643 = 3643;\n        b.value3644 = 3644;\n        b.value3645 = 3645;\n        b.value3646 = 3646;\n        b.value3647 = 3647;\n        b.value3648 = 3648;\n        b.value3649 = 3649;\n        b.value3650 = 3650;\n        b.value3651 = 3651;\n        b.value3652 = 3652;\n        b.value3653 = 3653;\n        b.value3654 = 3654;\n        b.value3655 = 3655;\n        b.value3656 = 3656;\n        b.value3657 = 3657;\n        b.value3658 = 3658;\n        b.value3659 = 3659;\n        b.value3660 = 3660;\n        b.value3661 = 3661;\n        b.value3662 = 3662;\n        b.value3663 = 3663;\n        b.value3664 = 3664;\n        b.value3665 = 3665;\n        b.value3666 = 3666;\n        b.value3667 = 3667;\n        b.value3668 = 3668;\n        b.value3669 = 3669;\n        b.value3670 = 3670;\n        b.value3671 = 3671;\n        b.value3672 = 3672;\n        b.value3673 = 3673;\n        b.value3674 = 3674;\n        b.value3675 = 3675;\n        b.value3676 = 3676;\n        b.value3677 = 3677;\n        b.value3678 = 3678;\n        b.value3679 = 3679;\n        b.value3680 = 3680;\n        b.value3681 = 3681;\n        b.value3682 = 3682;\n        b.value3683 = 3683;\n        b.value3684 = 3684;\n        b.value3685 = 3685;\n        b.value3686 = 3686;\n        b.value3687 = 3687;\n        b.value3688 = 3688;\n        b.value3689 = 3689;\n        b.value3690 = 3690;\n        b.value3691 = 3691;\n        b.value3692 = 3692;\n        b.value3693 = 3693;\n        b.value3694 = 3694;\n        b.value3695 = 3695;\n        b.value3696 = 3696;\n        b.value3697 = 3697;\n        b.value3698 = 3698;\n        b.value3699 = 3699;\n        b.value3700 = 3700;\n        b.value3701 = 3701;\n        b.value3702 = 3702;\n        b.value3703 = 3703;\n        b.value3704 = 3704;\n        b.value3705 = 3705;\n        b.value3706 = 3706;\n        b.value3707 = 3707;\n        b.value3708 = 3708;\n        b.value3709 = 3709;\n        b.value3710 = 3710;\n        b.value3711 = 3711;\n        b.value3712 = 3712;\n        b.value3713 = 3713;\n        b.value3714 = 3714;\n        b.value3715 = 3715;\n        b.value3716 = 3716;\n        b.value3717 = 3717;\n        b.value3718 = 3718;\n        b.value3719 = 3719;\n        b.value3720 = 3720;\n        b.value3721 = 3721;\n        b.value3722 = 3722;\n        b.value3723 = 3723;\n        b.value3724 = 3724;\n        b.value3725 = 3725;\n        b.value3726 = 3726;\n        b.value3727 = 3727;\n        b.value3728 = 3728;\n        b.value3729 = 3729;\n        b.value3730 = 3730;\n        b.value3731 = 3731;\n        b.value3732 = 3732;\n        b.value3733 = 3733;\n        b.value3734 = 3734;\n        b.value3735 = 3735;\n        b.value3736 = 3736;\n        b.value3737 = 3737;\n        b.value3738 = 3738;\n        b.value3739 = 3739;\n        b.value3740 = 3740;\n        b.value3741 = 3741;\n        b.value3742 = 3742;\n        b.value3743 = 3743;\n        b.value3744 = 3744;\n        b.value3745 = 3745;\n        b.value3746 = 3746;\n        b.value3747 = 3747;\n        b.value3748 = 3748;\n        b.value3749 = 3749;\n        b.value3750 = 3750;\n        b.value3751 = 3751;\n        b.value3752 = 3752;\n        b.value3753 = 3753;\n        b.value3754 = 3754;\n        b.value3755 = 3755;\n        b.value3756 = 3756;\n        b.value3757 = 3757;\n        b.value3758 = 3758;\n        b.value3759 = 3759;\n        b.value3760 = 3760;\n        b.value3761 = 3761;\n        b.value3762 = 3762;\n        b.value3763 = 3763;\n        b.value3764 = 3764;\n        b.value3765 = 3765;\n        b.value3766 = 3766;\n        b.value3767 = 3767;\n        b.value3768 = 3768;\n        b.value3769 = 3769;\n        b.value3770 = 3770;\n        b.value3771 = 3771;\n        b.value3772 = 3772;\n        b.value3773 = 3773;\n        b.value3774 = 3774;\n        b.value3775 = 3775;\n        b.value3776 = 3776;\n        b.value3777 = 3777;\n        b.value3778 = 3778;\n        b.value3779 = 3779;\n        b.value3780 = 3780;\n        b.value3781 = 3781;\n        b.value3782 = 3782;\n        b.value3783 = 3783;\n        b.value3784 = 3784;\n        b.value3785 = 3785;\n        b.value3786 = 3786;\n        b.value3787 = 3787;\n        b.value3788 = 3788;\n        b.value3789 = 3789;\n        b.value3790 = 3790;\n        b.value3791 = 3791;\n        b.value3792 = 3792;\n        b.value3793 = 3793;\n        b.value3794 = 3794;\n        b.value3795 = 3795;\n        b.value3796 = 3796;\n        b.value3797 = 3797;\n        b.value3798 = 3798;\n        b.value3799 = 3799;\n        b.value3800 = 3800;\n        b.value3801 = 3801;\n        b.value3802 = 3802;\n        b.value3803 = 3803;\n        b.value3804 = 3804;\n        b.value3805 = 3805;\n        b.value3806 = 3806;\n        b.value3807 = 3807;\n        b.value3808 = 3808;\n        b.value3809 = 3809;\n        b.value3810 = 3810;\n        b.value3811 = 3811;\n        b.value3812 = 3812;\n        b.value3813 = 3813;\n        b.value3814 = 3814;\n        b.value3815 = 3815;\n        b.value3816 = 3816;\n        b.value3817 = 3817;\n        b.value3818 = 3818;\n        b.value3819 = 3819;\n        b.value3820 = 3820;\n        b.value3821 = 3821;\n        b.value3822 = 3822;\n        b.value3823 = 3823;\n        b.value3824 = 3824;\n        b.value3825 = 3825;\n        b.value3826 = 3826;\n        b.value3827 = 3827;\n        b.value3828 = 3828;\n        b.value3829 = 3829;\n        b.value3830 = 3830;\n        b.value3831 = 3831;\n        b.value3832 = 3832;\n        b.value3833 = 3833;\n        b.value3834 = 3834;\n        b.value3835 = 3835;\n        b.value3836 = 3836;\n        b.value3837 = 3837;\n        b.value3838 = 3838;\n        b.value3839 = 3839;\n        b.value3840 = 3840;\n        b.value3841 = 3841;\n        b.value3842 = 3842;\n        b.value3843 = 3843;\n        b.value3844 = 3844;\n        b.value3845 = 3845;\n        b.value3846 = 3846;\n        b.value3847 = 3847;\n        b.value3848 = 3848;\n        b.value3849 = 3849;\n        b.value3850 = 3850;\n        b.value3851 = 3851;\n        b.value3852 = 3852;\n        b.value3853 = 3853;\n        b.value3854 = 3854;\n        b.value3855 = 3855;\n        b.value3856 = 3856;\n        b.value3857 = 3857;\n        b.value3858 = 3858;\n        b.value3859 = 3859;\n        b.value3860 = 3860;\n        b.value3861 = 3861;\n        b.value3862 = 3862;\n        b.value3863 = 3863;\n        b.value3864 = 3864;\n        b.value3865 = 3865;\n        b.value3866 = 3866;\n        b.value3867 = 3867;\n        b.value3868 = 3868;\n        b.value3869 = 3869;\n        b.value3870 = 3870;\n        b.value3871 = 3871;\n        b.value3872 = 3872;\n        b.value3873 = 3873;\n        b.value3874 = 3874;\n        b.value3875 = 3875;\n        b.value3876 = 3876;\n        b.value3877 = 3877;\n        b.value3878 = 3878;\n        b.value3879 = 3879;\n        b.value3880 = 3880;\n        b.value3881 = 3881;\n        b.value3882 = 3882;\n        b.value3883 = 3883;\n        b.value3884 = 3884;\n        b.value3885 = 3885;\n        b.value3886 = 3886;\n        b.value3887 = 3887;\n        b.value3888 = 3888;\n        b.value3889 = 3889;\n        b.value3890 = 3890;\n        b.value3891 = 3891;\n        b.value3892 = 3892;\n        b.value3893 = 3893;\n        b.value3894 = 3894;\n        b.value3895 = 3895;\n        b.value3896 = 3896;\n        b.value3897 = 3897;\n        b.value3898 = 3898;\n        b.value3899 = 3899;\n        b.value3900 = 3900;\n        b.value3901 = 3901;\n        b.value3902 = 3902;\n        b.value3903 = 3903;\n        b.value3904 = 3904;\n        b.value3905 = 3905;\n        b.value3906 = 3906;\n        b.value3907 = 3907;\n        b.value3908 = 3908;\n        b.value3909 = 3909;\n        b.value3910 = 3910;\n        b.value3911 = 3911;\n        b.value3912 = 3912;\n        b.value3913 = 3913;\n        b.value3914 = 3914;\n        b.value3915 = 3915;\n        b.value3916 = 3916;\n        b.value3917 = 3917;\n        b.value3918 = 3918;\n        b.value3919 = 3919;\n        b.value3920 = 3920;\n        b.value3921 = 3921;\n        b.value3922 = 3922;\n        b.value3923 = 3923;\n        b.value3924 = 3924;\n        b.value3925 = 3925;\n        b.value3926 = 3926;\n        b.value3927 = 3927;\n        b.value3928 = 3928;\n        b.value3929 = 3929;\n        b.value3930 = 3930;\n        b.value3931 = 3931;\n        b.value3932 = 3932;\n        b.value3933 = 3933;\n        b.value3934 = 3934;\n        b.value3935 = 3935;\n        b.value3936 = 3936;\n        b.value3937 = 3937;\n        b.value3938 = 3938;\n        b.value3939 = 3939;\n        b.value3940 = 3940;\n        b.value3941 = 3941;\n        b.value3942 = 3942;\n        b.value3943 = 3943;\n        b.value3944 = 3944;\n        b.value3945 = 3945;\n        b.value3946 = 3946;\n        b.value3947 = 3947;\n        b.value3948 = 3948;\n        b.value3949 = 3949;\n        b.value3950 = 3950;\n        b.value3951 = 3951;\n        b.value3952 = 3952;\n        b.value3953 = 3953;\n        b.value3954 = 3954;\n        b.value3955 = 3955;\n        b.value3956 = 3956;\n        b.value3957 = 3957;\n        b.value3958 = 3958;\n        b.value3959 = 3959;\n        b.value3960 = 3960;\n        b.value3961 = 3961;\n        b.value3962 = 3962;\n        b.value3963 = 3963;\n        b.value3964 = 3964;\n        b.value3965 = 3965;\n        b.value3966 = 3966;\n        b.value3967 = 3967;\n        b.value3968 = 3968;\n        b.value3969 = 3969;\n        b.value3970 = 3970;\n        b.value3971 = 3971;\n        b.value3972 = 3972;\n        b.value3973 = 3973;\n        b.value3974 = 3974;\n        b.value3975 = 3975;\n        b.value3976 = 3976;\n        b.value3977 = 3977;\n        b.value3978 = 3978;\n        b.value3979 = 3979;\n        b.value3980 = 3980;\n        b.value3981 = 3981;\n        b.value3982 = 3982;\n        b.value3983 = 3983;\n        b.value3984 = 3984;\n        b.value3985 = 3985;\n        b.value3986 = 3986;\n        b.value3987 = 3987;\n        b.value3988 = 3988;\n        b.value3989 = 3989;\n        b.value3990 = 3990;\n        b.value3991 = 3991;\n        b.value3992 = 3992;\n        b.value3993 = 3993;\n        b.value3994 = 3994;\n        b.value3995 = 3995;\n        b.value3996 = 3996;\n        b.value3997 = 3997;\n        b.value3998 = 3998;\n        b.value3999 = 3999;\n        b.value4000 = 4000;\n        b.value4001 = 4001;\n        b.value4002 = 4002;\n        b.value4003 = 4003;\n        b.value4004 = 4004;\n        b.value4005 = 4005;\n        b.value4006 = 4006;\n        b.value4007 = 4007;\n        b.value4008 = 4008;\n        b.value4009 = 4009;\n        b.value4010 = 4010;\n        b.value4011 = 4011;\n        b.value4012 = 4012;\n        b.value4013 = 4013;\n        b.value4014 = 4014;\n        b.value4015 = 4015;\n        b.value4016 = 4016;\n        b.value4017 = 4017;\n        b.value4018 = 4018;\n        b.value4019 = 4019;\n        b.value4020 = 4020;\n        b.value4021 = 4021;\n        b.value4022 = 4022;\n        b.value4023 = 4023;\n        b.value4024 = 4024;\n        b.value4025 = 4025;\n        b.value4026 = 4026;\n        b.value4027 = 4027;\n        b.value4028 = 4028;\n        b.value4029 = 4029;\n        b.value4030 = 4030;\n        b.value4031 = 4031;\n        b.value4032 = 4032;\n        b.value4033 = 4033;\n        b.value4034 = 4034;\n        b.value4035 = 4035;\n        b.value4036 = 4036;\n        b.value4037 = 4037;\n        b.value4038 = 4038;\n        b.value4039 = 4039;\n        b.value4040 = 4040;\n        b.value4041 = 4041;\n        b.value4042 = 4042;\n        b.value4043 = 4043;\n        b.value4044 = 4044;\n        b.value4045 = 4045;\n        b.value4046 = 4046;\n        b.value4047 = 4047;\n        b.value4048 = 4048;\n        b.value4049 = 4049;\n        b.value4050 = 4050;\n        b.value4051 = 4051;\n        b.value4052 = 4052;\n        b.value4053 = 4053;\n        b.value4054 = 4054;\n        b.value4055 = 4055;\n        b.value4056 = 4056;\n        b.value4057 = 4057;\n        b.value4058 = 4058;\n        b.value4059 = 4059;\n        b.value4060 = 4060;\n        b.value4061 = 4061;\n        b.value4062 = 4062;\n        b.value4063 = 4063;\n        b.value4064 = 4064;\n        b.value4065 = 4065;\n        b.value4066 = 4066;\n        b.value4067 = 4067;\n        b.value4068 = 4068;\n        b.value4069 = 4069;\n        b.value4070 = 4070;\n        b.value4071 = 4071;\n        b.value4072 = 4072;\n        b.value4073 = 4073;\n        b.value4074 = 4074;\n        b.value4075 = 4075;\n        b.value4076 = 4076;\n        b.value4077 = 4077;\n        b.value4078 = 4078;\n        b.value4079 = 4079;\n        b.value4080 = 4080;\n        b.value4081 = 4081;\n        b.value4082 = 4082;\n        b.value4083 = 4083;\n        b.value4084 = 4084;\n        b.value4085 = 4085;\n        b.value4086 = 4086;\n        b.value4087 = 4087;\n        b.value4088 = 4088;\n        b.value4089 = 4089;\n        b.value4090 = 4090;\n        b.value4091 = 4091;\n        b.value4092 = 4092;\n        b.value4093 = 4093;\n        b.value4094 = 4094;\n        b.value4095 = 4095;\n        b.value4096 = 4096;\n        b.value4097 = 4097;\n        b.value4098 = 4098;\n        b.value4099 = 4099;\n        b.value4100 = 4100;\n        b.value4101 = 4101;\n        b.value4102 = 4102;\n        b.value4103 = 4103;\n        b.value4104 = 4104;\n        b.value4105 = 4105;\n        b.value4106 = 4106;\n        b.value4107 = 4107;\n        b.value4108 = 4108;\n        b.value4109 = 4109;\n        b.value4110 = 4110;\n        b.value4111 = 4111;\n        b.value4112 = 4112;\n        b.value4113 = 4113;\n        b.value4114 = 4114;\n        b.value4115 = 4115;\n        b.value4116 = 4116;\n        b.value4117 = 4117;\n        b.value4118 = 4118;\n        b.value4119 = 4119;\n        b.value4120 = 4120;\n        b.value4121 = 4121;\n        b.value4122 = 4122;\n        b.value4123 = 4123;\n        b.value4124 = 4124;\n        b.value4125 = 4125;\n        b.value4126 = 4126;\n        b.value4127 = 4127;\n        b.value4128 = 4128;\n        b.value4129 = 4129;\n        b.value4130 = 4130;\n        b.value4131 = 4131;\n        b.value4132 = 4132;\n        b.value4133 = 4133;\n        b.value4134 = 4134;\n        b.value4135 = 4135;\n        b.value4136 = 4136;\n        b.value4137 = 4137;\n        b.value4138 = 4138;\n        b.value4139 = 4139;\n        b.value4140 = 4140;\n        b.value4141 = 4141;\n        b.value4142 = 4142;\n        b.value4143 = 4143;\n        b.value4144 = 4144;\n        b.value4145 = 4145;\n        b.value4146 = 4146;\n        b.value4147 = 4147;\n        b.value4148 = 4148;\n        b.value4149 = 4149;\n        b.value4150 = 4150;\n        b.value4151 = 4151;\n        b.value4152 = 4152;\n        b.value4153 = 4153;\n        b.value4154 = 4154;\n        b.value4155 = 4155;\n        b.value4156 = 4156;\n        b.value4157 = 4157;\n        b.value4158 = 4158;\n        b.value4159 = 4159;\n        b.value4160 = 4160;\n        b.value4161 = 4161;\n        b.value4162 = 4162;\n        b.value4163 = 4163;\n        b.value4164 = 4164;\n        b.value4165 = 4165;\n        b.value4166 = 4166;\n        b.value4167 = 4167;\n        b.value4168 = 4168;\n        b.value4169 = 4169;\n        b.value4170 = 4170;\n        b.value4171 = 4171;\n        b.value4172 = 4172;\n        b.value4173 = 4173;\n        b.value4174 = 4174;\n        b.value4175 = 4175;\n        b.value4176 = 4176;\n        b.value4177 = 4177;\n        b.value4178 = 4178;\n        b.value4179 = 4179;\n        b.value4180 = 4180;\n        b.value4181 = 4181;\n        b.value4182 = 4182;\n        b.value4183 = 4183;\n        b.value4184 = 4184;\n        b.value4185 = 4185;\n        b.value4186 = 4186;\n        b.value4187 = 4187;\n        b.value4188 = 4188;\n        b.value4189 = 4189;\n        b.value4190 = 4190;\n        b.value4191 = 4191;\n        b.value4192 = 4192;\n        b.value4193 = 4193;\n        b.value4194 = 4194;\n        b.value4195 = 4195;\n        b.value4196 = 4196;\n        b.value4197 = 4197;\n        b.value4198 = 4198;\n        b.value4199 = 4199;\n        b.value4200 = 4200;\n        b.value4201 = 4201;\n        b.value4202 = 4202;\n        b.value4203 = 4203;\n        b.value4204 = 4204;\n        b.value4205 = 4205;\n        b.value4206 = 4206;\n        b.value4207 = 4207;\n        b.value4208 = 4208;\n        b.value4209 = 4209;\n        b.value4210 = 4210;\n        b.value4211 = 4211;\n        b.value4212 = 4212;\n        b.value4213 = 4213;\n        b.value4214 = 4214;\n        b.value4215 = 4215;\n        b.value4216 = 4216;\n        b.value4217 = 4217;\n        b.value4218 = 4218;\n        b.value4219 = 4219;\n        b.value4220 = 4220;\n        b.value4221 = 4221;\n        b.value4222 = 4222;\n        b.value4223 = 4223;\n        b.value4224 = 4224;\n        b.value4225 = 4225;\n        b.value4226 = 4226;\n        b.value4227 = 4227;\n        b.value4228 = 4228;\n        b.value4229 = 4229;\n        b.value4230 = 4230;\n        b.value4231 = 4231;\n        b.value4232 = 4232;\n        b.value4233 = 4233;\n        b.value4234 = 4234;\n        b.value4235 = 4235;\n        b.value4236 = 4236;\n        b.value4237 = 4237;\n        b.value4238 = 4238;\n        b.value4239 = 4239;\n        b.value4240 = 4240;\n        b.value4241 = 4241;\n        b.value4242 = 4242;\n        b.value4243 = 4243;\n        b.value4244 = 4244;\n        b.value4245 = 4245;\n        b.value4246 = 4246;\n        b.value4247 = 4247;\n        b.value4248 = 4248;\n        b.value4249 = 4249;\n        b.value4250 = 4250;\n        b.value4251 = 4251;\n        b.value4252 = 4252;\n        b.value4253 = 4253;\n        b.value4254 = 4254;\n        b.value4255 = 4255;\n        b.value4256 = 4256;\n        b.value4257 = 4257;\n        b.value4258 = 4258;\n        b.value4259 = 4259;\n        b.value4260 = 4260;\n        b.value4261 = 4261;\n        b.value4262 = 4262;\n        b.value4263 = 4263;\n        b.value4264 = 4264;\n        b.value4265 = 4265;\n        b.value4266 = 4266;\n        b.value4267 = 4267;\n        b.value4268 = 4268;\n        b.value4269 = 4269;\n        b.value4270 = 4270;\n        b.value4271 = 4271;\n        b.value4272 = 4272;\n        b.value4273 = 4273;\n        b.value4274 = 4274;\n        b.value4275 = 4275;\n        b.value4276 = 4276;\n        b.value4277 = 4277;\n        b.value4278 = 4278;\n        b.value4279 = 4279;\n        b.value4280 = 4280;\n        b.value4281 = 4281;\n        b.value4282 = 4282;\n        b.value4283 = 4283;\n        b.value4284 = 4284;\n        b.value4285 = 4285;\n        b.value4286 = 4286;\n        b.value4287 = 4287;\n        b.value4288 = 4288;\n        b.value4289 = 4289;\n        b.value4290 = 4290;\n        b.value4291 = 4291;\n        b.value4292 = 4292;\n        b.value4293 = 4293;\n        b.value4294 = 4294;\n        b.value4295 = 4295;\n        b.value4296 = 4296;\n        b.value4297 = 4297;\n        b.value4298 = 4298;\n        b.value4299 = 4299;\n        b.value4300 = 4300;\n        b.value4301 = 4301;\n        b.value4302 = 4302;\n        b.value4303 = 4303;\n        b.value4304 = 4304;\n        b.value4305 = 4305;\n        b.value4306 = 4306;\n        b.value4307 = 4307;\n        b.value4308 = 4308;\n        b.value4309 = 4309;\n        b.value4310 = 4310;\n        b.value4311 = 4311;\n        b.value4312 = 4312;\n        b.value4313 = 4313;\n        b.value4314 = 4314;\n        b.value4315 = 4315;\n        b.value4316 = 4316;\n        b.value4317 = 4317;\n        b.value4318 = 4318;\n        b.value4319 = 4319;\n        b.value4320 = 4320;\n        b.value4321 = 4321;\n        b.value4322 = 4322;\n        b.value4323 = 4323;\n        b.value4324 = 4324;\n        b.value4325 = 4325;\n        b.value4326 = 4326;\n        b.value4327 = 4327;\n        b.value4328 = 4328;\n        b.value4329 = 4329;\n        b.value4330 = 4330;\n        b.value4331 = 4331;\n        b.value4332 = 4332;\n        b.value4333 = 4333;\n        b.value4334 = 4334;\n        b.value4335 = 4335;\n        b.value4336 = 4336;\n        b.value4337 = 4337;\n        b.value4338 = 4338;\n        b.value4339 = 4339;\n        b.value4340 = 4340;\n        b.value4341 = 4341;\n        b.value4342 = 4342;\n        b.value4343 = 4343;\n        b.value4344 = 4344;\n        b.value4345 = 4345;\n        b.value4346 = 4346;\n        b.value4347 = 4347;\n        b.value4348 = 4348;\n        b.value4349 = 4349;\n        b.value4350 = 4350;\n        b.value4351 = 4351;\n        b.value4352 = 4352;\n        b.value4353 = 4353;\n        b.value4354 = 4354;\n        b.value4355 = 4355;\n        b.value4356 = 4356;\n        b.value4357 = 4357;\n        b.value4358 = 4358;\n        b.value4359 = 4359;\n        b.value4360 = 4360;\n        b.value4361 = 4361;\n        b.value4362 = 4362;\n        b.value4363 = 4363;\n        b.value4364 = 4364;\n        b.value4365 = 4365;\n        b.value4366 = 4366;\n        b.value4367 = 4367;\n        b.value4368 = 4368;\n        b.value4369 = 4369;\n        b.value4370 = 4370;\n        b.value4371 = 4371;\n        b.value4372 = 4372;\n        b.value4373 = 4373;\n        b.value4374 = 4374;\n        b.value4375 = 4375;\n        b.value4376 = 4376;\n        b.value4377 = 4377;\n        b.value4378 = 4378;\n        b.value4379 = 4379;\n        b.value4380 = 4380;\n        b.value4381 = 4381;\n        b.value4382 = 4382;\n        b.value4383 = 4383;\n        b.value4384 = 4384;\n        b.value4385 = 4385;\n        b.value4386 = 4386;\n        b.value4387 = 4387;\n        b.value4388 = 4388;\n        b.value4389 = 4389;\n        b.value4390 = 4390;\n        b.value4391 = 4391;\n        b.value4392 = 4392;\n        b.value4393 = 4393;\n        b.value4394 = 4394;\n        b.value4395 = 4395;\n        b.value4396 = 4396;\n        b.value4397 = 4397;\n        b.value4398 = 4398;\n        b.value4399 = 4399;\n        b.value4400 = 4400;\n        b.value4401 = 4401;\n        b.value4402 = 4402;\n        b.value4403 = 4403;\n        b.value4404 = 4404;\n        b.value4405 = 4405;\n        b.value4406 = 4406;\n        b.value4407 = 4407;\n        b.value4408 = 4408;\n        b.value4409 = 4409;\n        b.value4410 = 4410;\n        b.value4411 = 4411;\n        b.value4412 = 4412;\n        b.value4413 = 4413;\n        b.value4414 = 4414;\n        b.value4415 = 4415;\n        b.value4416 = 4416;\n        b.value4417 = 4417;\n        b.value4418 = 4418;\n        b.value4419 = 4419;\n        b.value4420 = 4420;\n        b.value4421 = 4421;\n        b.value4422 = 4422;\n        b.value4423 = 4423;\n        b.value4424 = 4424;\n        b.value4425 = 4425;\n        b.value4426 = 4426;\n        b.value4427 = 4427;\n        b.value4428 = 4428;\n        b.value4429 = 4429;\n        b.value4430 = 4430;\n        b.value4431 = 4431;\n        b.value4432 = 4432;\n        b.value4433 = 4433;\n        b.value4434 = 4434;\n        b.value4435 = 4435;\n        b.value4436 = 4436;\n        b.value4437 = 4437;\n        b.value4438 = 4438;\n        b.value4439 = 4439;\n        b.value4440 = 4440;\n        b.value4441 = 4441;\n        b.value4442 = 4442;\n        b.value4443 = 4443;\n        b.value4444 = 4444;\n        b.value4445 = 4445;\n        b.value4446 = 4446;\n        b.value4447 = 4447;\n        b.value4448 = 4448;\n        b.value4449 = 4449;\n        b.value4450 = 4450;\n        b.value4451 = 4451;\n        b.value4452 = 4452;\n        b.value4453 = 4453;\n        b.value4454 = 4454;\n        b.value4455 = 4455;\n        b.value4456 = 4456;\n        b.value4457 = 4457;\n        b.value4458 = 4458;\n        b.value4459 = 4459;\n        b.value4460 = 4460;\n        b.value4461 = 4461;\n        b.value4462 = 4462;\n        b.value4463 = 4463;\n        b.value4464 = 4464;\n        b.value4465 = 4465;\n        b.value4466 = 4466;\n        b.value4467 = 4467;\n        b.value4468 = 4468;\n        b.value4469 = 4469;\n        b.value4470 = 4470;\n        b.value4471 = 4471;\n        b.value4472 = 4472;\n        b.value4473 = 4473;\n        b.value4474 = 4474;\n        b.value4475 = 4475;\n        b.value4476 = 4476;\n        b.value4477 = 4477;\n        b.value4478 = 4478;\n        b.value4479 = 4479;\n        b.value4480 = 4480;\n        b.value4481 = 4481;\n        b.value4482 = 4482;\n        b.value4483 = 4483;\n        b.value4484 = 4484;\n        b.value4485 = 4485;\n        b.value4486 = 4486;\n        b.value4487 = 4487;\n        b.value4488 = 4488;\n        b.value4489 = 4489;\n        b.value4490 = 4490;\n        b.value4491 = 4491;\n        b.value4492 = 4492;\n        b.value4493 = 4493;\n        b.value4494 = 4494;\n        b.value4495 = 4495;\n        b.value4496 = 4496;\n        b.value4497 = 4497;\n        b.value4498 = 4498;\n        b.value4499 = 4499;\n        b.value4500 = 4500;\n        b.value4501 = 4501;\n        b.value4502 = 4502;\n        b.value4503 = 4503;\n        b.value4504 = 4504;\n        b.value4505 = 4505;\n        b.value4506 = 4506;\n        b.value4507 = 4507;\n        b.value4508 = 4508;\n        b.value4509 = 4509;\n        b.value4510 = 4510;\n        b.value4511 = 4511;\n        b.value4512 = 4512;\n        b.value4513 = 4513;\n        b.value4514 = 4514;\n        b.value4515 = 4515;\n        b.value4516 = 4516;\n        b.value4517 = 4517;\n        b.value4518 = 4518;\n        b.value4519 = 4519;\n        b.value4520 = 4520;\n        b.value4521 = 4521;\n        b.value4522 = 4522;\n        b.value4523 = 4523;\n        b.value4524 = 4524;\n        b.value4525 = 4525;\n        b.value4526 = 4526;\n        b.value4527 = 4527;\n        b.value4528 = 4528;\n        b.value4529 = 4529;\n        b.value4530 = 4530;\n        b.value4531 = 4531;\n        b.value4532 = 4532;\n        b.value4533 = 4533;\n        b.value4534 = 4534;\n        b.value4535 = 4535;\n        b.value4536 = 4536;\n        b.value4537 = 4537;\n        b.value4538 = 4538;\n        b.value4539 = 4539;\n        b.value4540 = 4540;\n        b.value4541 = 4541;\n        b.value4542 = 4542;\n        b.value4543 = 4543;\n        b.value4544 = 4544;\n        b.value4545 = 4545;\n        b.value4546 = 4546;\n        b.value4547 = 4547;\n        b.value4548 = 4548;\n        b.value4549 = 4549;\n        b.value4550 = 4550;\n        b.value4551 = 4551;\n        b.value4552 = 4552;\n        b.value4553 = 4553;\n        b.value4554 = 4554;\n        b.value4555 = 4555;\n        b.value4556 = 4556;\n        b.value4557 = 4557;\n        b.value4558 = 4558;\n        b.value4559 = 4559;\n        b.value4560 = 4560;\n        b.value4561 = 4561;\n        b.value4562 = 4562;\n        b.value4563 = 4563;\n        b.value4564 = 4564;\n        b.value4565 = 4565;\n        b.value4566 = 4566;\n        b.value4567 = 4567;\n        b.value4568 = 4568;\n        b.value4569 = 4569;\n        b.value4570 = 4570;\n        b.value4571 = 4571;\n        b.value4572 = 4572;\n        b.value4573 = 4573;\n        b.value4574 = 4574;\n        b.value4575 = 4575;\n        b.value4576 = 4576;\n        b.value4577 = 4577;\n        b.value4578 = 4578;\n        b.value4579 = 4579;\n        b.value4580 = 4580;\n        b.value4581 = 4581;\n        b.value4582 = 4582;\n        b.value4583 = 4583;\n        b.value4584 = 4584;\n        b.value4585 = 4585;\n        b.value4586 = 4586;\n        b.value4587 = 4587;\n        b.value4588 = 4588;\n        b.value4589 = 4589;\n        b.value4590 = 4590;\n        b.value4591 = 4591;\n        b.value4592 = 4592;\n        b.value4593 = 4593;\n        b.value4594 = 4594;\n        b.value4595 = 4595;\n        b.value4596 = 4596;\n        b.value4597 = 4597;\n        b.value4598 = 4598;\n        b.value4599 = 4599;\n        b.value4600 = 4600;\n        b.value4601 = 4601;\n        b.value4602 = 4602;\n        b.value4603 = 4603;\n        b.value4604 = 4604;\n        b.value4605 = 4605;\n        b.value4606 = 4606;\n        b.value4607 = 4607;\n        b.value4608 = 4608;\n        b.value4609 = 4609;\n        b.value4610 = 4610;\n        b.value4611 = 4611;\n        b.value4612 = 4612;\n        b.value4613 = 4613;\n        b.value4614 = 4614;\n        b.value4615 = 4615;\n        b.value4616 = 4616;\n        b.value4617 = 4617;\n        b.value4618 = 4618;\n        b.value4619 = 4619;\n        b.value4620 = 4620;\n        b.value4621 = 4621;\n        b.value4622 = 4622;\n        b.value4623 = 4623;\n        b.value4624 = 4624;\n        b.value4625 = 4625;\n        b.value4626 = 4626;\n        b.value4627 = 4627;\n        b.value4628 = 4628;\n        b.value4629 = 4629;\n        b.value4630 = 4630;\n        b.value4631 = 4631;\n        b.value4632 = 4632;\n        b.value4633 = 4633;\n        b.value4634 = 4634;\n        b.value4635 = 4635;\n        b.value4636 = 4636;\n        b.value4637 = 4637;\n        b.value4638 = 4638;\n        b.value4639 = 4639;\n        b.value4640 = 4640;\n        b.value4641 = 4641;\n        b.value4642 = 4642;\n        b.value4643 = 4643;\n        b.value4644 = 4644;\n        b.value4645 = 4645;\n        b.value4646 = 4646;\n        b.value4647 = 4647;\n        b.value4648 = 4648;\n        b.value4649 = 4649;\n        b.value4650 = 4650;\n        b.value4651 = 4651;\n        b.value4652 = 4652;\n        b.value4653 = 4653;\n        b.value4654 = 4654;\n        b.value4655 = 4655;\n        b.value4656 = 4656;\n        b.value4657 = 4657;\n        b.value4658 = 4658;\n        b.value4659 = 4659;\n        b.value4660 = 4660;\n        b.value4661 = 4661;\n        b.value4662 = 4662;\n        b.value4663 = 4663;\n        b.value4664 = 4664;\n        b.value4665 = 4665;\n        b.value4666 = 4666;\n        b.value4667 = 4667;\n        b.value4668 = 4668;\n        b.value4669 = 4669;\n        b.value4670 = 4670;\n        b.value4671 = 4671;\n        b.value4672 = 4672;\n        b.value4673 = 4673;\n        b.value4674 = 4674;\n        b.value4675 = 4675;\n        b.value4676 = 4676;\n        b.value4677 = 4677;\n        b.value4678 = 4678;\n        b.value4679 = 4679;\n        b.value4680 = 4680;\n        b.value4681 = 4681;\n        b.value4682 = 4682;\n        b.value4683 = 4683;\n        b.value4684 = 4684;\n        b.value4685 = 4685;\n        b.value4686 = 4686;\n        b.value4687 = 4687;\n        b.value4688 = 4688;\n        b.value4689 = 4689;\n        b.value4690 = 4690;\n        b.value4691 = 4691;\n        b.value4692 = 4692;\n        b.value4693 = 4693;\n        b.value4694 = 4694;\n        b.value4695 = 4695;\n        b.value4696 = 4696;\n        b.value4697 = 4697;\n        b.value4698 = 4698;\n        b.value4699 = 4699;\n        b.value4700 = 4700;\n        b.value4701 = 4701;\n        b.value4702 = 4702;\n        b.value4703 = 4703;\n        b.value4704 = 4704;\n        b.value4705 = 4705;\n        b.value4706 = 4706;\n        b.value4707 = 4707;\n        b.value4708 = 4708;\n        b.value4709 = 4709;\n        b.value4710 = 4710;\n        b.value4711 = 4711;\n        b.value4712 = 4712;\n        b.value4713 = 4713;\n        b.value4714 = 4714;\n        b.value4715 = 4715;\n        b.value4716 = 4716;\n        b.value4717 = 4717;\n        b.value4718 = 4718;\n        b.value4719 = 4719;\n        b.value4720 = 4720;\n        b.value4721 = 4721;\n        b.value4722 = 4722;\n        b.value4723 = 4723;\n        b.value4724 = 4724;\n        b.value4725 = 4725;\n        b.value4726 = 4726;\n        b.value4727 = 4727;\n        b.value4728 = 4728;\n        b.value4729 = 4729;\n        b.value4730 = 4730;\n        b.value4731 = 4731;\n        b.value4732 = 4732;\n        b.value4733 = 4733;\n        b.value4734 = 4734;\n        b.value4735 = 4735;\n        b.value4736 = 4736;\n        b.value4737 = 4737;\n        b.value4738 = 4738;\n        b.value4739 = 4739;\n        b.value4740 = 4740;\n        b.value4741 = 4741;\n        b.value4742 = 4742;\n        b.value4743 = 4743;\n        b.value4744 = 4744;\n        b.value4745 = 4745;\n        b.value4746 = 4746;\n        b.value4747 = 4747;\n        b.value4748 = 4748;\n        b.value4749 = 4749;\n        b.value4750 = 4750;\n        b.value4751 = 4751;\n        b.value4752 = 4752;\n        b.value4753 = 4753;\n        b.value4754 = 4754;\n        b.value4755 = 4755;\n        b.value4756 = 4756;\n        b.value4757 = 4757;\n        b.value4758 = 4758;\n        b.value4759 = 4759;\n        b.value4760 = 4760;\n        b.value4761 = 4761;\n        b.value4762 = 4762;\n        b.value4763 = 4763;\n        b.value4764 = 4764;\n        b.value4765 = 4765;\n        b.value4766 = 4766;\n        b.value4767 = 4767;\n        b.value4768 = 4768;\n        b.value4769 = 4769;\n        b.value4770 = 4770;\n        b.value4771 = 4771;\n        b.value4772 = 4772;\n        b.value4773 = 4773;\n        b.value4774 = 4774;\n        b.value4775 = 4775;\n        b.value4776 = 4776;\n        b.value4777 = 4777;\n        b.value4778 = 4778;\n        b.value4779 = 4779;\n        b.value4780 = 4780;\n        b.value4781 = 4781;\n        b.value4782 = 4782;\n        b.value4783 = 4783;\n        b.value4784 = 4784;\n        b.value4785 = 4785;\n        b.value4786 = 4786;\n        b.value4787 = 4787;\n        b.value4788 = 4788;\n        b.value4789 = 4789;\n        b.value4790 = 4790;\n        b.value4791 = 4791;\n        b.value4792 = 4792;\n        b.value4793 = 4793;\n        b.value4794 = 4794;\n        b.value4795 = 4795;\n        b.value4796 = 4796;\n        b.value4797 = 4797;\n        b.value4798 = 4798;\n        b.value4799 = 4799;\n        b.value4800 = 4800;\n        b.value4801 = 4801;\n        b.value4802 = 4802;\n        b.value4803 = 4803;\n        b.value4804 = 4804;\n        b.value4805 = 4805;\n        b.value4806 = 4806;\n        b.value4807 = 4807;\n        b.value4808 = 4808;\n        b.value4809 = 4809;\n        b.value4810 = 4810;\n        b.value4811 = 4811;\n        b.value4812 = 4812;\n        b.value4813 = 4813;\n        b.value4814 = 4814;\n        b.value4815 = 4815;\n        b.value4816 = 4816;\n        b.value4817 = 4817;\n        b.value4818 = 4818;\n        b.value4819 = 4819;\n        b.value4820 = 4820;\n        b.value4821 = 4821;\n        b.value4822 = 4822;\n        b.value4823 = 4823;\n        b.value4824 = 4824;\n        b.value4825 = 4825;\n        b.value4826 = 4826;\n        b.value4827 = 4827;\n        b.value4828 = 4828;\n        b.value4829 = 4829;\n        b.value4830 = 4830;\n        b.value4831 = 4831;\n        b.value4832 = 4832;\n        b.value4833 = 4833;\n        b.value4834 = 4834;\n        b.value4835 = 4835;\n        b.value4836 = 4836;\n        b.value4837 = 4837;\n        b.value4838 = 4838;\n        b.value4839 = 4839;\n        b.value4840 = 4840;\n        b.value4841 = 4841;\n        b.value4842 = 4842;\n        b.value4843 = 4843;\n        b.value4844 = 4844;\n        b.value4845 = 4845;\n        b.value4846 = 4846;\n        b.value4847 = 4847;\n        b.value4848 = 4848;\n        b.value4849 = 4849;\n        b.value4850 = 4850;\n        b.value4851 = 4851;\n        b.value4852 = 4852;\n        b.value4853 = 4853;\n        b.value4854 = 4854;\n        b.value4855 = 4855;\n        b.value4856 = 4856;\n        b.value4857 = 4857;\n        b.value4858 = 4858;\n        b.value4859 = 4859;\n        b.value4860 = 4860;\n        b.value4861 = 4861;\n        b.value4862 = 4862;\n        b.value4863 = 4863;\n        b.value4864 = 4864;\n        b.value4865 = 4865;\n        b.value4866 = 4866;\n        b.value4867 = 4867;\n        b.value4868 = 4868;\n        b.value4869 = 4869;\n        b.value4870 = 4870;\n        b.value4871 = 4871;\n        b.value4872 = 4872;\n        b.value4873 = 4873;\n        b.value4874 = 4874;\n        b.value4875 = 4875;\n        b.value4876 = 4876;\n        b.value4877 = 4877;\n        b.value4878 = 4878;\n        b.value4879 = 4879;\n        b.value4880 = 4880;\n        b.value4881 = 4881;\n        b.value4882 = 4882;\n        b.value4883 = 4883;\n        b.value4884 = 4884;\n        b.value4885 = 4885;\n        b.value4886 = 4886;\n        b.value4887 = 4887;\n        b.value4888 = 4888;\n        b.value4889 = 4889;\n        b.value4890 = 4890;\n        b.value4891 = 4891;\n        b.value4892 = 4892;\n        b.value4893 = 4893;\n        b.value4894 = 4894;\n        b.value4895 = 4895;\n        b.value4896 = 4896;\n        b.value4897 = 4897;\n        b.value4898 = 4898;\n        b.value4899 = 4899;\n        b.value4900 = 4900;\n        b.value4901 = 4901;\n        b.value4902 = 4902;\n        b.value4903 = 4903;\n        b.value4904 = 4904;\n        b.value4905 = 4905;\n        b.value4906 = 4906;\n        b.value4907 = 4907;\n        b.value4908 = 4908;\n        b.value4909 = 4909;\n        b.value4910 = 4910;\n        b.value4911 = 4911;\n        b.value4912 = 4912;\n        b.value4913 = 4913;\n        b.value4914 = 4914;\n        b.value4915 = 4915;\n        b.value4916 = 4916;\n        b.value4917 = 4917;\n        b.value4918 = 4918;\n        b.value4919 = 4919;\n        b.value4920 = 4920;\n        b.value4921 = 4921;\n        b.value4922 = 4922;\n        b.value4923 = 4923;\n        b.value4924 = 4924;\n        b.value4925 = 4925;\n        b.value4926 = 4926;\n        b.value4927 = 4927;\n        b.value4928 = 4928;\n        b.value4929 = 4929;\n        b.value4930 = 4930;\n        b.value4931 = 4931;\n        b.value4932 = 4932;\n        b.value4933 = 4933;\n        b.value4934 = 4934;\n        b.value4935 = 4935;\n        b.value4936 = 4936;\n        b.value4937 = 4937;\n        b.value4938 = 4938;\n        b.value4939 = 4939;\n        b.value4940 = 4940;\n        b.value4941 = 4941;\n        b.value4942 = 4942;\n        b.value4943 = 4943;\n        b.value4944 = 4944;\n        b.value4945 = 4945;\n        b.value4946 = 4946;\n        b.value4947 = 4947;\n        b.value4948 = 4948;\n        b.value4949 = 4949;\n        b.value4950 = 4950;\n        b.value4951 = 4951;\n        b.value4952 = 4952;\n        b.value4953 = 4953;\n        b.value4954 = 4954;\n        b.value4955 = 4955;\n        b.value4956 = 4956;\n        b.value4957 = 4957;\n        b.value4958 = 4958;\n        b.value4959 = 4959;\n        b.value4960 = 4960;\n        b.value4961 = 4961;\n        b.value4962 = 4962;\n        b.value4963 = 4963;\n        b.value4964 = 4964;\n        b.value4965 = 4965;\n        b.value4966 = 4966;\n        b.value4967 = 4967;\n        b.value4968 = 4968;\n        b.value4969 = 4969;\n        b.value4970 = 4970;\n        b.value4971 = 4971;\n        b.value4972 = 4972;\n        b.value4973 = 4973;\n        b.value4974 = 4974;\n        b.value4975 = 4975;\n        b.value4976 = 4976;\n        b.value4977 = 4977;\n        b.value4978 = 4978;\n        b.value4979 = 4979;\n        b.value4980 = 4980;\n        b.value4981 = 4981;\n        b.value4982 = 4982;\n        b.value4983 = 4983;\n        b.value4984 = 4984;\n        b.value4985 = 4985;\n        b.value4986 = 4986;\n        b.value4987 = 4987;\n        b.value4988 = 4988;\n        b.value4989 = 4989;\n        b.value4990 = 4990;\n        b.value4991 = 4991;\n        b.value4992 = 4992;\n        b.value4993 = 4993;\n        b.value4994 = 4994;\n        b.value4995 = 4995;\n        b.value4996 = 4996;\n        b.value4997 = 4997;\n        b.value4998 = 4998;\n        b.value4999 = 4999;\n        b.value5000 = 5000;\n        b.value5001 = 5001;\n        b.value5002 = 5002;\n        b.value5003 = 5003;\n        b.value5004 = 5004;\n        b.value5005 = 5005;\n        b.value5006 = 5006;\n        b.value5007 = 5007;\n        b.value5008 = 5008;\n        b.value5009 = 5009;\n        b.value5010 = 5010;\n        b.value5011 = 5011;\n        b.value5012 = 5012;\n        b.value5013 = 5013;\n        b.value5014 = 5014;\n        b.value5015 = 5015;\n        b.value5016 = 5016;\n        b.value5017 = 5017;\n        b.value5018 = 5018;\n        b.value5019 = 5019;\n        b.value5020 = 5020;\n        b.value5021 = 5021;\n        b.value5022 = 5022;\n        b.value5023 = 5023;\n        b.value5024 = 5024;\n        b.value5025 = 5025;\n        b.value5026 = 5026;\n        b.value5027 = 5027;\n        b.value5028 = 5028;\n        b.value5029 = 5029;\n        b.value5030 = 5030;\n        b.value5031 = 5031;\n        b.value5032 = 5032;\n        b.value5033 = 5033;\n        b.value5034 = 5034;\n        b.value5035 = 5035;\n        b.value5036 = 5036;\n        b.value5037 = 5037;\n        b.value5038 = 5038;\n        b.value5039 = 5039;\n        b.value5040 = 5040;\n        b.value5041 = 5041;\n        b.value5042 = 5042;\n        b.value5043 = 5043;\n        b.value5044 = 5044;\n        b.value5045 = 5045;\n        b.value5046 = 5046;\n        b.value5047 = 5047;\n        b.value5048 = 5048;\n        b.value5049 = 5049;\n        b.value5050 = 5050;\n        b.value5051 = 5051;\n        b.value5052 = 5052;\n        b.value5053 = 5053;\n        b.value5054 = 5054;\n        b.value5055 = 5055;\n        b.value5056 = 5056;\n        b.value5057 = 5057;\n        b.value5058 = 5058;\n        b.value5059 = 5059;\n        b.value5060 = 5060;\n        b.value5061 = 5061;\n        b.value5062 = 5062;\n        b.value5063 = 5063;\n        b.value5064 = 5064;\n        b.value5065 = 5065;\n        b.value5066 = 5066;\n        b.value5067 = 5067;\n        b.value5068 = 5068;\n        b.value5069 = 5069;\n        b.value5070 = 5070;\n        b.value5071 = 5071;\n        b.value5072 = 5072;\n        b.value5073 = 5073;\n        b.value5074 = 5074;\n        b.value5075 = 5075;\n        b.value5076 = 5076;\n        b.value5077 = 5077;\n        b.value5078 = 5078;\n        b.value5079 = 5079;\n        b.value5080 = 5080;\n        b.value5081 = 5081;\n        b.value5082 = 5082;\n        b.value5083 = 5083;\n        b.value5084 = 5084;\n        b.value5085 = 5085;\n        b.value5086 = 5086;\n        b.value5087 = 5087;\n        b.value5088 = 5088;\n        b.value5089 = 5089;\n        b.value5090 = 5090;\n        b.value5091 = 5091;\n        b.value5092 = 5092;\n        b.value5093 = 5093;\n        b.value5094 = 5094;\n        b.value5095 = 5095;\n        b.value5096 = 5096;\n        b.value5097 = 5097;\n        b.value5098 = 5098;\n        b.value5099 = 5099;\n        b.value5100 = 5100;\n        b.value5101 = 5101;\n        b.value5102 = 5102;\n        b.value5103 = 5103;\n        b.value5104 = 5104;\n        b.value5105 = 5105;\n        b.value5106 = 5106;\n        b.value5107 = 5107;\n        b.value5108 = 5108;\n        b.value5109 = 5109;\n        b.value5110 = 5110;\n        b.value5111 = 5111;\n        b.value5112 = 5112;\n        b.value5113 = 5113;\n        b.value5114 = 5114;\n        b.value5115 = 5115;\n        b.value5116 = 5116;\n        b.value5117 = 5117;\n        b.value5118 = 5118;\n        b.value5119 = 5119;\n        b.value5120 = 5120;\n        b.value5121 = 5121;\n        b.value5122 = 5122;\n        b.value5123 = 5123;\n        b.value5124 = 5124;\n        b.value5125 = 5125;\n        b.value5126 = 5126;\n        b.value5127 = 5127;\n        b.value5128 = 5128;\n        b.value5129 = 5129;\n        b.value5130 = 5130;\n        b.value5131 = 5131;\n        b.value5132 = 5132;\n        b.value5133 = 5133;\n        b.value5134 = 5134;\n        b.value5135 = 5135;\n        b.value5136 = 5136;\n        b.value5137 = 5137;\n        b.value5138 = 5138;\n        b.value5139 = 5139;\n        b.value5140 = 5140;\n        b.value5141 = 5141;\n        b.value5142 = 5142;\n        b.value5143 = 5143;\n        b.value5144 = 5144;\n        b.value5145 = 5145;\n        b.value5146 = 5146;\n        b.value5147 = 5147;\n        b.value5148 = 5148;\n        b.value5149 = 5149;\n        b.value5150 = 5150;\n        b.value5151 = 5151;\n        b.value5152 = 5152;\n        b.value5153 = 5153;\n        b.value5154 = 5154;\n        b.value5155 = 5155;\n        b.value5156 = 5156;\n        b.value5157 = 5157;\n        b.value5158 = 5158;\n        b.value5159 = 5159;\n        b.value5160 = 5160;\n        b.value5161 = 5161;\n        b.value5162 = 5162;\n        b.value5163 = 5163;\n        b.value5164 = 5164;\n        b.value5165 = 5165;\n        b.value5166 = 5166;\n        b.value5167 = 5167;\n        b.value5168 = 5168;\n        b.value5169 = 5169;\n        b.value5170 = 5170;\n        b.value5171 = 5171;\n        b.value5172 = 5172;\n        b.value5173 = 5173;\n        b.value5174 = 5174;\n        b.value5175 = 5175;\n        b.value5176 = 5176;\n        b.value5177 = 5177;\n        b.value5178 = 5178;\n        b.value5179 = 5179;\n        b.value5180 = 5180;\n        b.value5181 = 5181;\n        b.value5182 = 5182;\n        b.value5183 = 5183;\n        b.value5184 = 5184;\n        b.value5185 = 5185;\n        b.value5186 = 5186;\n        b.value5187 = 5187;\n        b.value5188 = 5188;\n        b.value5189 = 5189;\n        b.value5190 = 5190;\n        b.value5191 = 5191;\n        b.value5192 = 5192;\n        b.value5193 = 5193;\n        b.value5194 = 5194;\n        b.value5195 = 5195;\n        b.value5196 = 5196;\n        b.value5197 = 5197;\n        b.value5198 = 5198;\n        b.value5199 = 5199;\n        b.value5200 = 5200;\n        b.value5201 = 5201;\n        b.value5202 = 5202;\n        b.value5203 = 5203;\n        b.value5204 = 5204;\n        b.value5205 = 5205;\n        b.value5206 = 5206;\n        b.value5207 = 5207;\n        b.value5208 = 5208;\n        b.value5209 = 5209;\n        b.value5210 = 5210;\n        b.value5211 = 5211;\n        b.value5212 = 5212;\n        b.value5213 = 5213;\n        b.value5214 = 5214;\n        b.value5215 = 5215;\n        b.value5216 = 5216;\n        b.value5217 = 5217;\n        b.value5218 = 5218;\n        b.value5219 = 5219;\n        b.value5220 = 5220;\n        b.value5221 = 5221;\n        b.value5222 = 5222;\n        b.value5223 = 5223;\n        b.value5224 = 5224;\n        b.value5225 = 5225;\n        b.value5226 = 5226;\n        b.value5227 = 5227;\n        b.value5228 = 5228;\n        b.value5229 = 5229;\n        b.value5230 = 5230;\n        b.value5231 = 5231;\n        b.value5232 = 5232;\n        b.value5233 = 5233;\n        b.value5234 = 5234;\n        b.value5235 = 5235;\n        b.value5236 = 5236;\n        b.value5237 = 5237;\n        b.value5238 = 5238;\n        b.value5239 = 5239;\n        b.value5240 = 5240;\n        b.value5241 = 5241;\n        b.value5242 = 5242;\n        b.value5243 = 5243;\n        b.value5244 = 5244;\n        b.value5245 = 5245;\n        b.value5246 = 5246;\n        b.value5247 = 5247;\n        b.value5248 = 5248;\n        b.value5249 = 5249;\n        b.value5250 = 5250;\n        b.value5251 = 5251;\n        b.value5252 = 5252;\n        b.value5253 = 5253;\n        b.value5254 = 5254;\n        b.value5255 = 5255;\n        b.value5256 = 5256;\n        b.value5257 = 5257;\n        b.value5258 = 5258;\n        b.value5259 = 5259;\n        b.value5260 = 5260;\n        b.value5261 = 5261;\n        b.value5262 = 5262;\n        b.value5263 = 5263;\n        b.value5264 = 5264;\n        b.value5265 = 5265;\n        b.value5266 = 5266;\n        b.value5267 = 5267;\n        b.value5268 = 5268;\n        b.value5269 = 5269;\n        b.value5270 = 5270;\n        b.value5271 = 5271;\n        b.value5272 = 5272;\n        b.value5273 = 5273;\n        b.value5274 = 5274;\n        b.value5275 = 5275;\n        b.value5276 = 5276;\n        b.value5277 = 5277;\n        b.value5278 = 5278;\n        b.value5279 = 5279;\n        b.value5280 = 5280;\n        b.value5281 = 5281;\n        b.value5282 = 5282;\n        b.value5283 = 5283;\n        b.value5284 = 5284;\n        b.value5285 = 5285;\n        b.value5286 = 5286;\n        b.value5287 = 5287;\n        b.value5288 = 5288;\n        b.value5289 = 5289;\n        b.value5290 = 5290;\n        b.value5291 = 5291;\n        b.value5292 = 5292;\n        b.value5293 = 5293;\n        b.value5294 = 5294;\n        b.value5295 = 5295;\n        b.value5296 = 5296;\n        b.value5297 = 5297;\n        b.value5298 = 5298;\n        b.value5299 = 5299;\n        b.value5300 = 5300;\n        b.value5301 = 5301;\n        b.value5302 = 5302;\n        b.value5303 = 5303;\n        b.value5304 = 5304;\n        b.value5305 = 5305;\n        b.value5306 = 5306;\n        b.value5307 = 5307;\n        b.value5308 = 5308;\n        b.value5309 = 5309;\n        b.value5310 = 5310;\n        b.value5311 = 5311;\n        b.value5312 = 5312;\n        b.value5313 = 5313;\n        b.value5314 = 5314;\n        b.value5315 = 5315;\n        b.value5316 = 5316;\n        b.value5317 = 5317;\n        b.value5318 = 5318;\n        b.value5319 = 5319;\n        b.value5320 = 5320;\n        b.value5321 = 5321;\n        b.value5322 = 5322;\n        b.value5323 = 5323;\n        b.value5324 = 5324;\n        b.value5325 = 5325;\n        b.value5326 = 5326;\n        b.value5327 = 5327;\n        b.value5328 = 5328;\n        b.value5329 = 5329;\n        b.value5330 = 5330;\n        b.value5331 = 5331;\n        b.value5332 = 5332;\n        b.value5333 = 5333;\n        b.value5334 = 5334;\n        b.value5335 = 5335;\n        b.value5336 = 5336;\n        b.value5337 = 5337;\n        b.value5338 = 5338;\n        b.value5339 = 5339;\n        b.value5340 = 5340;\n        b.value5341 = 5341;\n        b.value5342 = 5342;\n        b.value5343 = 5343;\n        b.value5344 = 5344;\n        b.value5345 = 5345;\n        b.value5346 = 5346;\n        b.value5347 = 5347;\n        b.value5348 = 5348;\n        b.value5349 = 5349;\n        b.value5350 = 5350;\n        b.value5351 = 5351;\n        b.value5352 = 5352;\n        b.value5353 = 5353;\n        b.value5354 = 5354;\n        b.value5355 = 5355;\n        b.value5356 = 5356;\n        b.value5357 = 5357;\n        b.value5358 = 5358;\n        b.value5359 = 5359;\n        b.value5360 = 5360;\n        b.value5361 = 5361;\n        b.value5362 = 5362;\n        b.value5363 = 5363;\n        b.value5364 = 5364;\n        b.value5365 = 5365;\n        b.value5366 = 5366;\n        b.value5367 = 5367;\n        b.value5368 = 5368;\n        b.value5369 = 5369;\n        b.value5370 = 5370;\n        b.value5371 = 5371;\n        b.value5372 = 5372;\n        b.value5373 = 5373;\n        b.value5374 = 5374;\n        b.value5375 = 5375;\n        b.value5376 = 5376;\n        b.value5377 = 5377;\n        b.value5378 = 5378;\n        b.value5379 = 5379;\n        b.value5380 = 5380;\n        b.value5381 = 5381;\n        b.value5382 = 5382;\n        b.value5383 = 5383;\n        b.value5384 = 5384;\n        b.value5385 = 5385;\n        b.value5386 = 5386;\n        b.value5387 = 5387;\n        b.value5388 = 5388;\n        b.value5389 = 5389;\n        b.value5390 = 5390;\n        b.value5391 = 5391;\n        b.value5392 = 5392;\n        b.value5393 = 5393;\n        b.value5394 = 5394;\n        b.value5395 = 5395;\n        b.value5396 = 5396;\n        b.value5397 = 5397;\n        b.value5398 = 5398;\n        b.value5399 = 5399;\n        b.value5400 = 5400;\n        b.value5401 = 5401;\n        b.value5402 = 5402;\n        b.value5403 = 5403;\n        b.value5404 = 5404;\n        b.value5405 = 5405;\n        b.value5406 = 5406;\n        b.value5407 = 5407;\n        b.value5408 = 5408;\n        b.value5409 = 5409;\n        b.value5410 = 5410;\n        b.value5411 = 5411;\n        b.value5412 = 5412;\n        b.value5413 = 5413;\n        b.value5414 = 5414;\n        b.value5415 = 5415;\n        b.value5416 = 5416;\n        b.value5417 = 5417;\n        b.value5418 = 5418;\n        b.value5419 = 5419;\n        b.value5420 = 5420;\n        b.value5421 = 5421;\n        b.value5422 = 5422;\n        b.value5423 = 5423;\n        b.value5424 = 5424;\n        b.value5425 = 5425;\n        b.value5426 = 5426;\n        b.value5427 = 5427;\n        b.value5428 = 5428;\n        b.value5429 = 5429;\n        b.value5430 = 5430;\n        b.value5431 = 5431;\n        b.value5432 = 5432;\n        b.value5433 = 5433;\n        b.value5434 = 5434;\n        b.value5435 = 5435;\n        b.value5436 = 5436;\n        b.value5437 = 5437;\n        b.value5438 = 5438;\n        b.value5439 = 5439;\n        b.value5440 = 5440;\n        b.value5441 = 5441;\n        b.value5442 = 5442;\n        b.value5443 = 5443;\n        b.value5444 = 5444;\n        b.value5445 = 5445;\n        b.value5446 = 5446;\n        b.value5447 = 5447;\n        b.value5448 = 5448;\n        b.value5449 = 5449;\n        b.value5450 = 5450;\n        b.value5451 = 5451;\n        b.value5452 = 5452;\n        b.value5453 = 5453;\n        b.value5454 = 5454;\n        b.value5455 = 5455;\n        b.value5456 = 5456;\n        b.value5457 = 5457;\n        b.value5458 = 5458;\n        b.value5459 = 5459;\n        b.value5460 = 5460;\n        b.value5461 = 5461;\n        b.value5462 = 5462;\n        b.value5463 = 5463;\n        b.value5464 = 5464;\n        b.value5465 = 5465;\n        b.value5466 = 5466;\n        b.value5467 = 5467;\n        b.value5468 = 5468;\n        b.value5469 = 5469;\n        b.value5470 = 5470;\n        b.value5471 = 5471;\n        b.value5472 = 5472;\n        b.value5473 = 5473;\n        b.value5474 = 5474;\n        b.value5475 = 5475;\n        b.value5476 = 5476;\n        b.value5477 = 5477;\n        b.value5478 = 5478;\n        b.value5479 = 5479;\n        b.value5480 = 5480;\n        b.value5481 = 5481;\n        b.value5482 = 5482;\n        b.value5483 = 5483;\n        b.value5484 = 5484;\n        b.value5485 = 5485;\n        b.value5486 = 5486;\n        b.value5487 = 5487;\n        b.value5488 = 5488;\n        b.value5489 = 5489;\n        b.value5490 = 5490;\n        b.value5491 = 5491;\n        b.value5492 = 5492;\n        b.value5493 = 5493;\n        b.value5494 = 5494;\n        b.value5495 = 5495;\n        b.value5496 = 5496;\n        b.value5497 = 5497;\n        b.value5498 = 5498;\n        b.value5499 = 5499;\n        b.value5500 = 5500;\n        b.value5501 = 5501;\n        b.value5502 = 5502;\n        b.value5503 = 5503;\n        b.value5504 = 5504;\n        b.value5505 = 5505;\n        b.value5506 = 5506;\n        b.value5507 = 5507;\n        b.value5508 = 5508;\n        b.value5509 = 5509;\n        b.value5510 = 5510;\n        b.value5511 = 5511;\n        b.value5512 = 5512;\n        b.value5513 = 5513;\n        b.value5514 = 5514;\n        b.value5515 = 5515;\n        b.value5516 = 5516;\n        b.value5517 = 5517;\n        b.value5518 = 5518;\n        b.value5519 = 5519;\n        b.value5520 = 5520;\n        b.value5521 = 5521;\n        b.value5522 = 5522;\n        b.value5523 = 5523;\n        b.value5524 = 5524;\n        b.value5525 = 5525;\n        b.value5526 = 5526;\n        b.value5527 = 5527;\n        b.value5528 = 5528;\n        b.value5529 = 5529;\n        b.value5530 = 5530;\n        b.value5531 = 5531;\n        b.value5532 = 5532;\n        b.value5533 = 5533;\n        b.value5534 = 5534;\n        b.value5535 = 5535;\n        b.value5536 = 5536;\n        b.value5537 = 5537;\n        b.value5538 = 5538;\n        b.value5539 = 5539;\n        b.value5540 = 5540;\n        b.value5541 = 5541;\n        b.value5542 = 5542;\n        b.value5543 = 5543;\n        b.value5544 = 5544;\n        b.value5545 = 5545;\n        b.value5546 = 5546;\n        b.value5547 = 5547;\n        b.value5548 = 5548;\n        b.value5549 = 5549;\n        b.value5550 = 5550;\n        b.value5551 = 5551;\n        b.value5552 = 5552;\n        b.value5553 = 5553;\n        b.value5554 = 5554;\n        b.value5555 = 5555;\n        b.value5556 = 5556;\n        b.value5557 = 5557;\n        b.value5558 = 5558;\n        b.value5559 = 5559;\n        b.value5560 = 5560;\n        b.value5561 = 5561;\n        b.value5562 = 5562;\n        b.value5563 = 5563;\n        b.value5564 = 5564;\n        b.value5565 = 5565;\n        b.value5566 = 5566;\n        b.value5567 = 5567;\n        b.value5568 = 5568;\n        b.value5569 = 5569;\n        b.value5570 = 5570;\n        b.value5571 = 5571;\n        b.value5572 = 5572;\n        b.value5573 = 5573;\n        b.value5574 = 5574;\n        b.value5575 = 5575;\n        b.value5576 = 5576;\n        b.value5577 = 5577;\n        b.value5578 = 5578;\n        b.value5579 = 5579;\n        b.value5580 = 5580;\n        b.value5581 = 5581;\n        b.value5582 = 5582;\n        b.value5583 = 5583;\n        b.value5584 = 5584;\n        b.value5585 = 5585;\n        b.value5586 = 5586;\n        b.value5587 = 5587;\n        b.value5588 = 5588;\n        b.value5589 = 5589;\n        b.value5590 = 5590;\n        b.value5591 = 5591;\n        b.value5592 = 5592;\n        b.value5593 = 5593;\n        b.value5594 = 5594;\n        b.value5595 = 5595;\n        b.value5596 = 5596;\n        b.value5597 = 5597;\n        b.value5598 = 5598;\n        b.value5599 = 5599;\n        b.value5600 = 5600;\n        b.value5601 = 5601;\n        b.value5602 = 5602;\n        b.value5603 = 5603;\n        b.value5604 = 5604;\n        b.value5605 = 5605;\n        b.value5606 = 5606;\n        b.value5607 = 5607;\n        b.value5608 = 5608;\n        b.value5609 = 5609;\n        b.value5610 = 5610;\n        b.value5611 = 5611;\n        b.value5612 = 5612;\n        b.value5613 = 5613;\n        b.value5614 = 5614;\n        b.value5615 = 5615;\n        b.value5616 = 5616;\n        b.value5617 = 5617;\n        b.value5618 = 5618;\n        b.value5619 = 5619;\n        b.value5620 = 5620;\n        b.value5621 = 5621;\n        b.value5622 = 5622;\n        b.value5623 = 5623;\n        b.value5624 = 5624;\n        b.value5625 = 5625;\n        b.value5626 = 5626;\n        b.value5627 = 5627;\n        b.value5628 = 5628;\n        b.value5629 = 5629;\n        b.value5630 = 5630;\n        b.value5631 = 5631;\n        b.value5632 = 5632;\n        b.value5633 = 5633;\n        b.value5634 = 5634;\n        b.value5635 = 5635;\n        b.value5636 = 5636;\n        b.value5637 = 5637;\n        b.value5638 = 5638;\n        b.value5639 = 5639;\n        b.value5640 = 5640;\n        b.value5641 = 5641;\n        b.value5642 = 5642;\n        b.value5643 = 5643;\n        b.value5644 = 5644;\n        b.value5645 = 5645;\n        b.value5646 = 5646;\n        b.value5647 = 5647;\n        b.value5648 = 5648;\n        b.value5649 = 5649;\n        b.value5650 = 5650;\n        b.value5651 = 5651;\n        b.value5652 = 5652;\n        b.value5653 = 5653;\n        b.value5654 = 5654;\n        b.value5655 = 5655;\n        b.value5656 = 5656;\n        b.value5657 = 5657;\n        b.value5658 = 5658;\n        b.value5659 = 5659;\n        b.value5660 = 5660;\n        b.value5661 = 5661;\n        b.value5662 = 5662;\n        b.value5663 = 5663;\n        b.value5664 = 5664;\n        b.value5665 = 5665;\n        b.value5666 = 5666;\n        b.value5667 = 5667;\n        b.value5668 = 5668;\n        b.value5669 = 5669;\n        b.value5670 = 5670;\n        b.value5671 = 5671;\n        b.value5672 = 5672;\n        b.value5673 = 5673;\n        b.value5674 = 5674;\n        b.value5675 = 5675;\n        b.value5676 = 5676;\n        b.value5677 = 5677;\n        b.value5678 = 5678;\n        b.value5679 = 5679;\n        b.value5680 = 5680;\n        b.value5681 = 5681;\n        b.value5682 = 5682;\n        b.value5683 = 5683;\n        b.value5684 = 5684;\n        b.value5685 = 5685;\n        b.value5686 = 5686;\n        b.value5687 = 5687;\n        b.value5688 = 5688;\n        b.value5689 = 5689;\n        b.value5690 = 5690;\n        b.value5691 = 5691;\n        b.value5692 = 5692;\n        b.value5693 = 5693;\n        b.value5694 = 5694;\n        b.value5695 = 5695;\n        b.value5696 = 5696;\n        b.value5697 = 5697;\n        b.value5698 = 5698;\n        b.value5699 = 5699;\n        b.value5700 = 5700;\n        b.value5701 = 5701;\n        b.value5702 = 5702;\n        b.value5703 = 5703;\n        b.value5704 = 5704;\n        b.value5705 = 5705;\n        b.value5706 = 5706;\n        b.value5707 = 5707;\n        b.value5708 = 5708;\n        b.value5709 = 5709;\n        b.value5710 = 5710;\n        b.value5711 = 5711;\n        b.value5712 = 5712;\n        b.value5713 = 5713;\n        b.value5714 = 5714;\n        b.value5715 = 5715;\n        b.value5716 = 5716;\n        b.value5717 = 5717;\n        b.value5718 = 5718;\n        b.value5719 = 5719;\n        b.value5720 = 5720;\n        b.value5721 = 5721;\n        b.value5722 = 5722;\n        b.value5723 = 5723;\n        b.value5724 = 5724;\n        b.value5725 = 5725;\n        b.value5726 = 5726;\n        b.value5727 = 5727;\n        b.value5728 = 5728;\n        b.value5729 = 5729;\n        b.value5730 = 5730;\n        b.value5731 = 5731;\n        b.value5732 = 5732;\n        b.value5733 = 5733;\n        b.value5734 = 5734;\n        b.value5735 = 5735;\n        b.value5736 = 5736;\n        b.value5737 = 5737;\n        b.value5738 = 5738;\n        b.value5739 = 5739;\n        b.value5740 = 5740;\n        b.value5741 = 5741;\n        b.value5742 = 5742;\n        b.value5743 = 5743;\n        b.value5744 = 5744;\n        b.value5745 = 5745;\n        b.value5746 = 5746;\n        b.value5747 = 5747;\n        b.value5748 = 5748;\n        b.value5749 = 5749;\n        b.value5750 = 5750;\n        b.value5751 = 5751;\n        b.value5752 = 5752;\n        b.value5753 = 5753;\n        b.value5754 = 5754;\n        b.value5755 = 5755;\n        b.value5756 = 5756;\n        b.value5757 = 5757;\n        b.value5758 = 5758;\n        b.value5759 = 5759;\n        b.value5760 = 5760;\n        b.value5761 = 5761;\n        b.value5762 = 5762;\n        b.value5763 = 5763;\n        b.value5764 = 5764;\n        b.value5765 = 5765;\n        b.value5766 = 5766;\n        b.value5767 = 5767;\n        b.value5768 = 5768;\n        b.value5769 = 5769;\n        b.value5770 = 5770;\n        b.value5771 = 5771;\n        b.value5772 = 5772;\n        b.value5773 = 5773;\n        b.value5774 = 5774;\n        b.value5775 = 5775;\n        b.value5776 = 5776;\n        b.value5777 = 5777;\n        b.value5778 = 5778;\n        b.value5779 = 5779;\n        b.value5780 = 5780;\n        b.value5781 = 5781;\n        b.value5782 = 5782;\n        b.value5783 = 5783;\n        b.value5784 = 5784;\n        b.value5785 = 5785;\n        b.value5786 = 5786;\n        b.value5787 = 5787;\n        b.value5788 = 5788;\n        b.value5789 = 5789;\n        b.value5790 = 5790;\n        b.value5791 = 5791;\n        b.value5792 = 5792;\n        b.value5793 = 5793;\n        b.value5794 = 5794;\n        b.value5795 = 5795;\n        b.value5796 = 5796;\n        b.value5797 = 5797;\n        b.value5798 = 5798;\n        b.value5799 = 5799;\n        b.value5800 = 5800;\n        b.value5801 = 5801;\n        b.value5802 = 5802;\n        b.value5803 = 5803;\n        b.value5804 = 5804;\n        b.value5805 = 5805;\n        b.value5806 = 5806;\n        b.value5807 = 5807;\n        b.value5808 = 5808;\n        b.value5809 = 5809;\n        b.value5810 = 5810;\n        b.value5811 = 5811;\n        b.value5812 = 5812;\n        b.value5813 = 5813;\n        b.value5814 = 5814;\n        b.value5815 = 5815;\n        b.value5816 = 5816;\n        b.value5817 = 5817;\n        b.value5818 = 5818;\n        b.value5819 = 5819;\n        b.value5820 = 5820;\n        b.value5821 = 5821;\n        b.value5822 = 5822;\n        b.value5823 = 5823;\n        b.value5824 = 5824;\n        b.value5825 = 5825;\n        b.value5826 = 5826;\n        b.value5827 = 5827;\n        b.value5828 = 5828;\n        b.value5829 = 5829;\n        b.value5830 = 5830;\n        b.value5831 = 5831;\n        b.value5832 = 5832;\n        b.value5833 = 5833;\n        b.value5834 = 5834;\n        b.value5835 = 5835;\n        b.value5836 = 5836;\n        b.value5837 = 5837;\n        b.value5838 = 5838;\n        b.value5839 = 5839;\n        b.value5840 = 5840;\n        b.value5841 = 5841;\n        b.value5842 = 5842;\n        b.value5843 = 5843;\n        b.value5844 = 5844;\n        b.value5845 = 5845;\n        b.value5846 = 5846;\n        b.value5847 = 5847;\n        b.value5848 = 5848;\n        b.value5849 = 5849;\n        b.value5850 = 5850;\n        b.value5851 = 5851;\n        b.value5852 = 5852;\n        b.value5853 = 5853;\n        b.value5854 = 5854;\n        b.value5855 = 5855;\n        b.value5856 = 5856;\n        b.value5857 = 5857;\n        b.value5858 = 5858;\n        b.value5859 = 5859;\n        b.value5860 = 5860;\n        b.value5861 = 5861;\n        b.value5862 = 5862;\n        b.value5863 = 5863;\n        b.value5864 = 5864;\n        b.value5865 = 5865;\n        b.value5866 = 5866;\n        b.value5867 = 5867;\n        b.value5868 = 5868;\n        b.value5869 = 5869;\n        b.value5870 = 5870;\n        b.value5871 = 5871;\n        b.value5872 = 5872;\n        b.value5873 = 5873;\n        b.value5874 = 5874;\n        b.value5875 = 5875;\n        b.value5876 = 5876;\n        b.value5877 = 5877;\n        b.value5878 = 5878;\n        b.value5879 = 5879;\n        b.value5880 = 5880;\n        b.value5881 = 5881;\n        b.value5882 = 5882;\n        b.value5883 = 5883;\n        b.value5884 = 5884;\n        b.value5885 = 5885;\n        b.value5886 = 5886;\n        b.value5887 = 5887;\n        b.value5888 = 5888;\n        b.value5889 = 5889;\n        b.value5890 = 5890;\n        b.value5891 = 5891;\n        b.value5892 = 5892;\n        b.value5893 = 5893;\n        b.value5894 = 5894;\n        b.value5895 = 5895;\n        b.value5896 = 5896;\n        b.value5897 = 5897;\n        b.value5898 = 5898;\n        b.value5899 = 5899;\n        b.value5900 = 5900;\n        b.value5901 = 5901;\n        b.value5902 = 5902;\n        b.value5903 = 5903;\n        b.value5904 = 5904;\n        b.value5905 = 5905;\n        b.value5906 = 5906;\n        b.value5907 = 5907;\n        b.value5908 = 5908;\n        b.value5909 = 5909;\n        b.value5910 = 5910;\n        b.value5911 = 5911;\n        b.value5912 = 5912;\n        b.value5913 = 5913;\n        b.value5914 = 5914;\n        b.value5915 = 5915;\n        b.value5916 = 5916;\n        b.value5917 = 5917;\n        b.value5918 = 5918;\n        b.value5919 = 5919;\n        b.value5920 = 5920;\n        b.value5921 = 5921;\n        b.value5922 = 5922;\n        b.value5923 = 5923;\n        b.value5924 = 5924;\n        b.value5925 = 5925;\n        b.value5926 = 5926;\n        b.value5927 = 5927;\n        b.value5928 = 5928;\n        b.value5929 = 5929;\n        b.value5930 = 5930;\n        b.value5931 = 5931;\n        b.value5932 = 5932;\n        b.value5933 = 5933;\n        b.value5934 = 5934;\n        b.value5935 = 5935;\n        b.value5936 = 5936;\n        b.value5937 = 5937;\n        b.value5938 = 5938;\n        b.value5939 = 5939;\n        b.value5940 = 5940;\n        b.value5941 = 5941;\n        b.value5942 = 5942;\n        b.value5943 = 5943;\n        b.value5944 = 5944;\n        b.value5945 = 5945;\n        b.value5946 = 5946;\n        b.value5947 = 5947;\n        b.value5948 = 5948;\n        b.value5949 = 5949;\n        b.value5950 = 5950;\n        b.value5951 = 5951;\n        b.value5952 = 5952;\n        b.value5953 = 5953;\n        b.value5954 = 5954;\n        b.value5955 = 5955;\n        b.value5956 = 5956;\n        b.value5957 = 5957;\n        b.value5958 = 5958;\n        b.value5959 = 5959;\n        b.value5960 = 5960;\n        b.value5961 = 5961;\n        b.value5962 = 5962;\n        b.value5963 = 5963;\n        b.value5964 = 5964;\n        b.value5965 = 5965;\n        b.value5966 = 5966;\n        b.value5967 = 5967;\n        b.value5968 = 5968;\n        b.value5969 = 5969;\n        b.value5970 = 5970;\n        b.value5971 = 5971;\n        b.value5972 = 5972;\n        b.value5973 = 5973;\n        b.value5974 = 5974;\n        b.value5975 = 5975;\n        b.value5976 = 5976;\n        b.value5977 = 5977;\n        b.value5978 = 5978;\n        b.value5979 = 5979;\n        b.value5980 = 5980;\n        b.value5981 = 5981;\n        b.value5982 = 5982;\n        b.value5983 = 5983;\n        b.value5984 = 5984;\n        b.value5985 = 5985;\n        b.value5986 = 5986;\n        b.value5987 = 5987;\n        b.value5988 = 5988;\n        b.value5989 = 5989;\n        b.value5990 = 5990;\n        b.value5991 = 5991;\n        b.value5992 = 5992;\n        b.value5993 = 5993;\n        b.value5994 = 5994;\n        b.value5995 = 5995;\n        b.value5996 = 5996;\n        b.value5997 = 5997;\n        b.value5998 = 5998;\n        b.value5999 = 5999;\n        b.value6000 = 6000;\n        b.value6001 = 6001;\n        b.value6002 = 6002;\n        b.value6003 = 6003;\n        b.value6004 = 6004;\n        b.value6005 = 6005;\n        b.value6006 = 6006;\n        b.value6007 = 6007;\n        b.value6008 = 6008;\n        b.value6009 = 6009;\n        b.value6010 = 6010;\n        b.value6011 = 6011;\n        b.value6012 = 6012;\n        b.value6013 = 6013;\n        b.value6014 = 6014;\n        b.value6015 = 6015;\n        b.value6016 = 6016;\n        b.value6017 = 6017;\n        b.value6018 = 6018;\n        b.value6019 = 6019;\n        b.value6020 = 6020;\n        b.value6021 = 6021;\n        b.value6022 = 6022;\n        b.value6023 = 6023;\n        b.value6024 = 6024;\n        b.value6025 = 6025;\n        b.value6026 = 6026;\n        b.value6027 = 6027;\n        b.value6028 = 6028;\n        b.value6029 = 6029;\n        b.value6030 = 6030;\n        b.value6031 = 6031;\n        b.value6032 = 6032;\n        b.value6033 = 6033;\n        b.value6034 = 6034;\n        b.value6035 = 6035;\n        b.value6036 = 6036;\n        b.value6037 = 6037;\n        b.value6038 = 6038;\n        b.value6039 = 6039;\n        b.value6040 = 6040;\n        b.value6041 = 6041;\n        b.value6042 = 6042;\n        b.value6043 = 6043;\n        b.value6044 = 6044;\n        b.value6045 = 6045;\n        b.value6046 = 6046;\n        b.value6047 = 6047;\n        b.value6048 = 6048;\n        b.value6049 = 6049;\n        b.value6050 = 6050;\n        b.value6051 = 6051;\n        b.value6052 = 6052;\n        b.value6053 = 6053;\n        b.value6054 = 6054;\n        b.value6055 = 6055;\n        b.value6056 = 6056;\n        b.value6057 = 6057;\n        b.value6058 = 6058;\n        b.value6059 = 6059;\n        b.value6060 = 6060;\n        b.value6061 = 6061;\n        b.value6062 = 6062;\n        b.value6063 = 6063;\n        b.value6064 = 6064;\n        b.value6065 = 6065;\n        b.value6066 = 6066;\n        b.value6067 = 6067;\n        b.value6068 = 6068;\n        b.value6069 = 6069;\n        b.value6070 = 6070;\n        b.value6071 = 6071;\n        b.value6072 = 6072;\n        b.value6073 = 6073;\n        b.value6074 = 6074;\n        b.value6075 = 6075;\n        b.value6076 = 6076;\n        b.value6077 = 6077;\n        b.value6078 = 6078;\n        b.value6079 = 6079;\n        b.value6080 = 6080;\n        b.value6081 = 6081;\n        b.value6082 = 6082;\n        b.value6083 = 6083;\n        b.value6084 = 6084;\n        b.value6085 = 6085;\n        b.value6086 = 6086;\n        b.value6087 = 6087;\n        b.value6088 = 6088;\n        b.value6089 = 6089;\n        b.value6090 = 6090;\n        b.value6091 = 6091;\n        b.value6092 = 6092;\n        b.value6093 = 6093;\n        b.value6094 = 6094;\n        b.value6095 = 6095;\n        b.value6096 = 6096;\n        b.value6097 = 6097;\n        b.value6098 = 6098;\n        b.value6099 = 6099;\n        b.value6100 = 6100;\n        b.value6101 = 6101;\n        b.value6102 = 6102;\n        b.value6103 = 6103;\n        b.value6104 = 6104;\n        b.value6105 = 6105;\n        b.value6106 = 6106;\n        b.value6107 = 6107;\n        b.value6108 = 6108;\n        b.value6109 = 6109;\n        b.value6110 = 6110;\n        b.value6111 = 6111;\n        b.value6112 = 6112;\n        b.value6113 = 6113;\n        b.value6114 = 6114;\n        b.value6115 = 6115;\n        b.value6116 = 6116;\n        b.value6117 = 6117;\n        b.value6118 = 6118;\n        b.value6119 = 6119;\n        b.value6120 = 6120;\n        b.value6121 = 6121;\n        b.value6122 = 6122;\n        b.value6123 = 6123;\n        b.value6124 = 6124;\n        b.value6125 = 6125;\n        b.value6126 = 6126;\n        b.value6127 = 6127;\n        b.value6128 = 6128;\n        b.value6129 = 6129;\n        b.value6130 = 6130;\n        b.value6131 = 6131;\n        b.value6132 = 6132;\n        b.value6133 = 6133;\n        b.value6134 = 6134;\n        b.value6135 = 6135;\n        b.value6136 = 6136;\n        b.value6137 = 6137;\n        b.value6138 = 6138;\n        b.value6139 = 6139;\n        b.value6140 = 6140;\n        b.value6141 = 6141;\n        b.value6142 = 6142;\n        b.value6143 = 6143;\n        b.value6144 = 6144;\n        b.value6145 = 6145;\n        b.value6146 = 6146;\n        b.value6147 = 6147;\n        b.value6148 = 6148;\n        b.value6149 = 6149;\n        b.value6150 = 6150;\n        b.value6151 = 6151;\n        b.value6152 = 6152;\n        b.value6153 = 6153;\n        b.value6154 = 6154;\n        b.value6155 = 6155;\n        b.value6156 = 6156;\n        b.value6157 = 6157;\n        b.value6158 = 6158;\n        b.value6159 = 6159;\n        b.value6160 = 6160;\n        b.value6161 = 6161;\n        b.value6162 = 6162;\n        b.value6163 = 6163;\n        b.value6164 = 6164;\n        b.value6165 = 6165;\n        b.value6166 = 6166;\n        b.value6167 = 6167;\n        b.value6168 = 6168;\n        b.value6169 = 6169;\n        b.value6170 = 6170;\n        b.value6171 = 6171;\n        b.value6172 = 6172;\n        b.value6173 = 6173;\n        b.value6174 = 6174;\n        b.value6175 = 6175;\n        b.value6176 = 6176;\n        b.value6177 = 6177;\n        b.value6178 = 6178;\n        b.value6179 = 6179;\n        b.value6180 = 6180;\n        b.value6181 = 6181;\n        b.value6182 = 6182;\n        b.value6183 = 6183;\n        b.value6184 = 6184;\n        b.value6185 = 6185;\n        b.value6186 = 6186;\n        b.value6187 = 6187;\n        b.value6188 = 6188;\n        b.value6189 = 6189;\n        b.value6190 = 6190;\n        b.value6191 = 6191;\n        b.value6192 = 6192;\n        b.value6193 = 6193;\n        b.value6194 = 6194;\n        b.value6195 = 6195;\n        b.value6196 = 6196;\n        b.value6197 = 6197;\n        b.value6198 = 6198;\n        b.value6199 = 6199;\n        b.value6200 = 6200;\n        b.value6201 = 6201;\n        b.value6202 = 6202;\n        b.value6203 = 6203;\n        b.value6204 = 6204;\n        b.value6205 = 6205;\n        b.value6206 = 6206;\n        b.value6207 = 6207;\n        b.value6208 = 6208;\n        b.value6209 = 6209;\n        b.value6210 = 6210;\n        b.value6211 = 6211;\n        b.value6212 = 6212;\n        b.value6213 = 6213;\n        b.value6214 = 6214;\n        b.value6215 = 6215;\n        b.value6216 = 6216;\n        b.value6217 = 6217;\n        b.value6218 = 6218;\n        b.value6219 = 6219;\n        b.value6220 = 6220;\n        b.value6221 = 6221;\n        b.value6222 = 6222;\n        b.value6223 = 6223;\n        b.value6224 = 6224;\n        b.value6225 = 6225;\n        b.value6226 = 6226;\n        b.value6227 = 6227;\n        b.value6228 = 6228;\n        b.value6229 = 6229;\n        b.value6230 = 6230;\n        b.value6231 = 6231;\n        b.value6232 = 6232;\n        b.value6233 = 6233;\n        b.value6234 = 6234;\n        b.value6235 = 6235;\n        b.value6236 = 6236;\n        b.value6237 = 6237;\n        b.value6238 = 6238;\n        b.value6239 = 6239;\n        b.value6240 = 6240;\n        b.value6241 = 6241;\n        b.value6242 = 6242;\n        b.value6243 = 6243;\n        b.value6244 = 6244;\n        b.value6245 = 6245;\n        b.value6246 = 6246;\n        b.value6247 = 6247;\n        b.value6248 = 6248;\n        b.value6249 = 6249;\n        b.value6250 = 6250;\n        b.value6251 = 6251;\n        b.value6252 = 6252;\n        b.value6253 = 6253;\n        b.value6254 = 6254;\n        b.value6255 = 6255;\n        b.value6256 = 6256;\n        b.value6257 = 6257;\n        b.value6258 = 6258;\n        b.value6259 = 6259;\n        b.value6260 = 6260;\n        b.value6261 = 6261;\n        b.value6262 = 6262;\n        b.value6263 = 6263;\n        b.value6264 = 6264;\n        b.value6265 = 6265;\n        b.value6266 = 6266;\n        b.value6267 = 6267;\n        b.value6268 = 6268;\n        b.value6269 = 6269;\n        b.value6270 = 6270;\n        b.value6271 = 6271;\n        b.value6272 = 6272;\n        b.value6273 = 6273;\n        b.value6274 = 6274;\n        b.value6275 = 6275;\n        b.value6276 = 6276;\n        b.value6277 = 6277;\n        b.value6278 = 6278;\n        b.value6279 = 6279;\n        b.value6280 = 6280;\n        b.value6281 = 6281;\n        b.value6282 = 6282;\n        b.value6283 = 6283;\n        b.value6284 = 6284;\n        b.value6285 = 6285;\n        b.value6286 = 6286;\n        b.value6287 = 6287;\n        b.value6288 = 6288;\n        b.value6289 = 6289;\n        b.value6290 = 6290;\n        b.value6291 = 6291;\n        b.value6292 = 6292;\n        b.value6293 = 6293;\n        b.value6294 = 6294;\n        b.value6295 = 6295;\n        b.value6296 = 6296;\n        b.value6297 = 6297;\n        b.value6298 = 6298;\n        b.value6299 = 6299;\n        b.value6300 = 6300;\n        b.value6301 = 6301;\n        b.value6302 = 6302;\n        b.value6303 = 6303;\n        b.value6304 = 6304;\n        b.value6305 = 6305;\n        b.value6306 = 6306;\n        b.value6307 = 6307;\n        b.value6308 = 6308;\n        b.value6309 = 6309;\n        b.value6310 = 6310;\n        b.value6311 = 6311;\n        b.value6312 = 6312;\n        b.value6313 = 6313;\n        b.value6314 = 6314;\n        b.value6315 = 6315;\n        b.value6316 = 6316;\n        b.value6317 = 6317;\n        b.value6318 = 6318;\n        b.value6319 = 6319;\n        b.value6320 = 6320;\n        b.value6321 = 6321;\n        b.value6322 = 6322;\n        b.value6323 = 6323;\n        b.value6324 = 6324;\n        b.value6325 = 6325;\n        b.value6326 = 6326;\n        b.value6327 = 6327;\n        b.value6328 = 6328;\n        b.value6329 = 6329;\n        b.value6330 = 6330;\n        b.value6331 = 6331;\n        b.value6332 = 6332;\n        b.value6333 = 6333;\n        b.value6334 = 6334;\n        b.value6335 = 6335;\n        b.value6336 = 6336;\n        b.value6337 = 6337;\n        b.value6338 = 6338;\n        b.value6339 = 6339;\n        b.value6340 = 6340;\n        b.value6341 = 6341;\n        b.value6342 = 6342;\n        b.value6343 = 6343;\n        b.value6344 = 6344;\n        b.value6345 = 6345;\n        b.value6346 = 6346;\n        b.value6347 = 6347;\n        b.value6348 = 6348;\n        b.value6349 = 6349;\n        b.value6350 = 6350;\n        b.value6351 = 6351;\n        b.value6352 = 6352;\n        b.value6353 = 6353;\n        b.value6354 = 6354;\n        b.value6355 = 6355;\n        b.value6356 = 6356;\n        b.value6357 = 6357;\n        b.value6358 = 6358;\n        b.value6359 = 6359;\n        b.value6360 = 6360;\n        b.value6361 = 6361;\n        b.value6362 = 6362;\n        b.value6363 = 6363;\n        b.value6364 = 6364;\n        b.value6365 = 6365;\n        b.value6366 = 6366;\n        b.value6367 = 6367;\n        b.value6368 = 6368;\n        b.value6369 = 6369;\n        b.value6370 = 6370;\n        b.value6371 = 6371;\n        b.value6372 = 6372;\n        b.value6373 = 6373;\n        b.value6374 = 6374;\n        b.value6375 = 6375;\n        b.value6376 = 6376;\n        b.value6377 = 6377;\n        b.value6378 = 6378;\n        b.value6379 = 6379;\n        b.value6380 = 6380;\n        b.value6381 = 6381;\n        b.value6382 = 6382;\n        b.value6383 = 6383;\n        b.value6384 = 6384;\n        b.value6385 = 6385;\n        b.value6386 = 6386;\n        b.value6387 = 6387;\n        b.value6388 = 6388;\n        b.value6389 = 6389;\n        b.value6390 = 6390;\n        b.value6391 = 6391;\n        b.value6392 = 6392;\n        b.value6393 = 6393;\n        b.value6394 = 6394;\n        b.value6395 = 6395;\n        b.value6396 = 6396;\n        b.value6397 = 6397;\n        b.value6398 = 6398;\n        b.value6399 = 6399;\n        b.value6400 = 6400;\n        b.value6401 = 6401;\n        b.value6402 = 6402;\n        b.value6403 = 6403;\n        b.value6404 = 6404;\n        b.value6405 = 6405;\n        b.value6406 = 6406;\n        b.value6407 = 6407;\n        b.value6408 = 6408;\n        b.value6409 = 6409;\n        b.value6410 = 6410;\n        b.value6411 = 6411;\n        b.value6412 = 6412;\n        b.value6413 = 6413;\n        b.value6414 = 6414;\n        b.value6415 = 6415;\n        b.value6416 = 6416;\n        b.value6417 = 6417;\n        b.value6418 = 6418;\n        b.value6419 = 6419;\n        b.value6420 = 6420;\n        b.value6421 = 6421;\n        b.value6422 = 6422;\n        b.value6423 = 6423;\n        b.value6424 = 6424;\n        b.value6425 = 6425;\n        b.value6426 = 6426;\n        b.value6427 = 6427;\n        b.value6428 = 6428;\n        b.value6429 = 6429;\n        b.value6430 = 6430;\n        b.value6431 = 6431;\n        b.value6432 = 6432;\n        b.value6433 = 6433;\n        b.value6434 = 6434;\n        b.value6435 = 6435;\n        b.value6436 = 6436;\n        b.value6437 = 6437;\n        b.value6438 = 6438;\n        b.value6439 = 6439;\n        b.value6440 = 6440;\n        b.value6441 = 6441;\n        b.value6442 = 6442;\n        b.value6443 = 6443;\n        b.value6444 = 6444;\n        b.value6445 = 6445;\n        b.value6446 = 6446;\n        b.value6447 = 6447;\n        b.value6448 = 6448;\n        b.value6449 = 6449;\n        b.value6450 = 6450;\n        b.value6451 = 6451;\n        b.value6452 = 6452;\n        b.value6453 = 6453;\n        b.value6454 = 6454;\n        b.value6455 = 6455;\n        b.value6456 = 6456;\n        b.value6457 = 6457;\n        b.value6458 = 6458;\n        b.value6459 = 6459;\n        b.value6460 = 6460;\n        b.value6461 = 6461;\n        b.value6462 = 6462;\n        b.value6463 = 6463;\n        b.value6464 = 6464;\n        b.value6465 = 6465;\n        b.value6466 = 6466;\n        b.value6467 = 6467;\n        b.value6468 = 6468;\n        b.value6469 = 6469;\n        b.value6470 = 6470;\n        b.value6471 = 6471;\n        b.value6472 = 6472;\n        b.value6473 = 6473;\n        b.value6474 = 6474;\n        b.value6475 = 6475;\n        b.value6476 = 6476;\n        b.value6477 = 6477;\n        b.value6478 = 6478;\n        b.value6479 = 6479;\n        b.value6480 = 6480;\n        b.value6481 = 6481;\n        b.value6482 = 6482;\n        b.value6483 = 6483;\n        b.value6484 = 6484;\n        b.value6485 = 6485;\n        b.value6486 = 6486;\n        b.value6487 = 6487;\n        b.value6488 = 6488;\n        b.value6489 = 6489;\n        b.value6490 = 6490;\n        b.value6491 = 6491;\n        b.value6492 = 6492;\n        b.value6493 = 6493;\n        b.value6494 = 6494;\n        b.value6495 = 6495;\n        b.value6496 = 6496;\n        b.value6497 = 6497;\n        b.value6498 = 6498;\n        b.value6499 = 6499;\n        b.value6500 = 6500;\n        b.value6501 = 6501;\n        b.value6502 = 6502;\n        b.value6503 = 6503;\n        b.value6504 = 6504;\n        b.value6505 = 6505;\n        b.value6506 = 6506;\n        b.value6507 = 6507;\n        b.value6508 = 6508;\n        b.value6509 = 6509;\n        b.value6510 = 6510;\n        b.value6511 = 6511;\n        b.value6512 = 6512;\n        b.value6513 = 6513;\n        b.value6514 = 6514;\n        b.value6515 = 6515;\n        b.value6516 = 6516;\n        b.value6517 = 6517;\n        b.value6518 = 6518;\n        b.value6519 = 6519;\n        b.value6520 = 6520;\n        b.value6521 = 6521;\n        b.value6522 = 6522;\n        b.value6523 = 6523;\n        b.value6524 = 6524;\n        b.value6525 = 6525;\n        b.value6526 = 6526;\n        b.value6527 = 6527;\n        b.value6528 = 6528;\n        b.value6529 = 6529;\n        b.value6530 = 6530;\n        b.value6531 = 6531;\n        b.value6532 = 6532;\n        b.value6533 = 6533;\n        b.value6534 = 6534;\n        b.value6535 = 6535;\n        b.value6536 = 6536;\n        b.value6537 = 6537;\n        b.value6538 = 6538;\n        b.value6539 = 6539;\n        b.value6540 = 6540;\n        b.value6541 = 6541;\n        b.value6542 = 6542;\n        b.value6543 = 6543;\n        b.value6544 = 6544;\n        b.value6545 = 6545;\n        b.value6546 = 6546;\n        b.value6547 = 6547;\n        b.value6548 = 6548;\n        b.value6549 = 6549;\n        b.value6550 = 6550;\n        b.value6551 = 6551;\n        b.value6552 = 6552;\n        b.value6553 = 6553;\n        b.value6554 = 6554;\n        b.value6555 = 6555;\n        b.value6556 = 6556;\n        b.value6557 = 6557;\n        b.value6558 = 6558;\n        b.value6559 = 6559;\n        b.value6560 = 6560;\n        b.value6561 = 6561;\n        b.value6562 = 6562;\n        b.value6563 = 6563;\n        b.value6564 = 6564;\n        b.value6565 = 6565;\n        b.value6566 = 6566;\n        b.value6567 = 6567;\n        b.value6568 = 6568;\n        b.value6569 = 6569;\n        b.value6570 = 6570;\n        b.value6571 = 6571;\n        b.value6572 = 6572;\n        b.value6573 = 6573;\n        b.value6574 = 6574;\n        b.value6575 = 6575;\n        b.value6576 = 6576;\n        b.value6577 = 6577;\n        b.value6578 = 6578;\n        b.value6579 = 6579;\n        b.value6580 = 6580;\n        b.value6581 = 6581;\n        b.value6582 = 6582;\n        b.value6583 = 6583;\n        b.value6584 = 6584;\n        b.value6585 = 6585;\n        b.value6586 = 6586;\n        b.value6587 = 6587;\n        b.value6588 = 6588;\n        b.value6589 = 6589;\n        b.value6590 = 6590;\n        b.value6591 = 6591;\n        b.value6592 = 6592;\n        b.value6593 = 6593;\n        b.value6594 = 6594;\n        b.value6595 = 6595;\n        b.value6596 = 6596;\n        b.value6597 = 6597;\n        b.value6598 = 6598;\n        b.value6599 = 6599;\n        b.value6600 = 6600;\n        b.value6601 = 6601;\n        b.value6602 = 6602;\n        b.value6603 = 6603;\n        b.value6604 = 6604;\n        b.value6605 = 6605;\n        b.value6606 = 6606;\n        b.value6607 = 6607;\n        b.value6608 = 6608;\n        b.value6609 = 6609;\n        b.value6610 = 6610;\n        b.value6611 = 6611;\n        b.value6612 = 6612;\n        b.value6613 = 6613;\n        b.value6614 = 6614;\n        b.value6615 = 6615;\n        b.value6616 = 6616;\n        b.value6617 = 6617;\n        b.value6618 = 6618;\n        b.value6619 = 6619;\n        b.value6620 = 6620;\n        b.value6621 = 6621;\n        b.value6622 = 6622;\n        b.value6623 = 6623;\n        b.value6624 = 6624;\n        b.value6625 = 6625;\n        b.value6626 = 6626;\n        b.value6627 = 6627;\n        b.value6628 = 6628;\n        b.value6629 = 6629;\n        b.value6630 = 6630;\n        b.value6631 = 6631;\n        b.value6632 = 6632;\n        b.value6633 = 6633;\n        b.value6634 = 6634;\n        b.value6635 = 6635;\n        b.value6636 = 6636;\n        b.value6637 = 6637;\n        b.value6638 = 6638;\n        b.value6639 = 6639;\n        b.value6640 = 6640;\n        b.value6641 = 6641;\n        b.value6642 = 6642;\n        b.value6643 = 6643;\n        b.value6644 = 6644;\n        b.value6645 = 6645;\n        b.value6646 = 6646;\n        b.value6647 = 6647;\n        b.value6648 = 6648;\n        b.value6649 = 6649;\n        b.value6650 = 6650;\n        b.value6651 = 6651;\n        b.value6652 = 6652;\n        b.value6653 = 6653;\n        b.value6654 = 6654;\n        b.value6655 = 6655;\n        b.value6656 = 6656;\n        b.value6657 = 6657;\n        b.value6658 = 6658;\n        b.value6659 = 6659;\n        b.value6660 = 6660;\n        b.value6661 = 6661;\n        b.value6662 = 6662;\n        b.value6663 = 6663;\n        b.value6664 = 6664;\n        b.value6665 = 6665;\n        b.value6666 = 6666;\n        b.value6667 = 6667;\n        b.value6668 = 6668;\n        b.value6669 = 6669;\n        b.value6670 = 6670;\n        b.value6671 = 6671;\n        b.value6672 = 6672;\n        b.value6673 = 6673;\n        b.value6674 = 6674;\n        b.value6675 = 6675;\n        b.value6676 = 6676;\n        b.value6677 = 6677;\n        b.value6678 = 6678;\n        b.value6679 = 6679;\n        b.value6680 = 6680;\n        b.value6681 = 6681;\n        b.value6682 = 6682;\n        b.value6683 = 6683;\n        b.value6684 = 6684;\n        b.value6685 = 6685;\n        b.value6686 = 6686;\n        b.value6687 = 6687;\n        b.value6688 = 6688;\n        b.value6689 = 6689;\n        b.value6690 = 6690;\n        b.value6691 = 6691;\n        b.value6692 = 6692;\n        b.value6693 = 6693;\n        b.value6694 = 6694;\n        b.value6695 = 6695;\n        b.value6696 = 6696;\n        b.value6697 = 6697;\n        b.value6698 = 6698;\n        b.value6699 = 6699;\n        b.value6700 = 6700;\n        b.value6701 = 6701;\n        b.value6702 = 6702;\n        b.value6703 = 6703;\n        b.value6704 = 6704;\n        b.value6705 = 6705;\n        b.value6706 = 6706;\n        b.value6707 = 6707;\n        b.value6708 = 6708;\n        b.value6709 = 6709;\n        b.value6710 = 6710;\n        b.value6711 = 6711;\n        b.value6712 = 6712;\n        b.value6713 = 6713;\n        b.value6714 = 6714;\n        b.value6715 = 6715;\n        b.value6716 = 6716;\n        b.value6717 = 6717;\n        b.value6718 = 6718;\n        b.value6719 = 6719;\n        b.value6720 = 6720;\n        b.value6721 = 6721;\n        b.value6722 = 6722;\n        b.value6723 = 6723;\n        b.value6724 = 6724;\n        b.value6725 = 6725;\n        b.value6726 = 6726;\n        b.value6727 = 6727;\n        b.value6728 = 6728;\n        b.value6729 = 6729;\n        b.value6730 = 6730;\n        b.value6731 = 6731;\n        b.value6732 = 6732;\n        b.value6733 = 6733;\n        b.value6734 = 6734;\n        b.value6735 = 6735;\n        b.value6736 = 6736;\n        b.value6737 = 6737;\n        b.value6738 = 6738;\n        b.value6739 = 6739;\n        b.value6740 = 6740;\n        b.value6741 = 6741;\n        b.value6742 = 6742;\n        b.value6743 = 6743;\n        b.value6744 = 6744;\n        b.value6745 = 6745;\n        b.value6746 = 6746;\n        b.value6747 = 6747;\n        b.value6748 = 6748;\n        b.value6749 = 6749;\n        b.value6750 = 6750;\n        b.value6751 = 6751;\n        b.value6752 = 6752;\n        b.value6753 = 6753;\n        b.value6754 = 6754;\n        b.value6755 = 6755;\n        b.value6756 = 6756;\n        b.value6757 = 6757;\n        b.value6758 = 6758;\n        b.value6759 = 6759;\n        b.value6760 = 6760;\n        b.value6761 = 6761;\n        b.value6762 = 6762;\n        b.value6763 = 6763;\n        b.value6764 = 6764;\n        b.value6765 = 6765;\n        b.value6766 = 6766;\n        b.value6767 = 6767;\n        b.value6768 = 6768;\n        b.value6769 = 6769;\n        b.value6770 = 6770;\n        b.value6771 = 6771;\n        b.value6772 = 6772;\n        b.value6773 = 6773;\n        b.value6774 = 6774;\n        b.value6775 = 6775;\n        b.value6776 = 6776;\n        b.value6777 = 6777;\n        b.value6778 = 6778;\n        b.value6779 = 6779;\n        b.value6780 = 6780;\n        b.value6781 = 6781;\n        b.value6782 = 6782;\n        b.value6783 = 6783;\n        b.value6784 = 6784;\n        b.value6785 = 6785;\n        b.value6786 = 6786;\n        b.value6787 = 6787;\n        b.value6788 = 6788;\n        b.value6789 = 6789;\n        b.value6790 = 6790;\n        b.value6791 = 6791;\n        b.value6792 = 6792;\n        b.value6793 = 6793;\n        b.value6794 = 6794;\n        b.value6795 = 6795;\n        b.value6796 = 6796;\n        b.value6797 = 6797;\n        b.value6798 = 6798;\n        b.value6799 = 6799;\n        b.value6800 = 6800;\n        b.value6801 = 6801;\n        b.value6802 = 6802;\n        b.value6803 = 6803;\n        b.value6804 = 6804;\n        b.value6805 = 6805;\n        b.value6806 = 6806;\n        b.value6807 = 6807;\n        b.value6808 = 6808;\n        b.value6809 = 6809;\n        b.value6810 = 6810;\n        b.value6811 = 6811;\n        b.value6812 = 6812;\n        b.value6813 = 6813;\n        b.value6814 = 6814;\n        b.value6815 = 6815;\n        b.value6816 = 6816;\n        b.value6817 = 6817;\n        b.value6818 = 6818;\n        b.value6819 = 6819;\n        b.value6820 = 6820;\n        b.value6821 = 6821;\n        b.value6822 = 6822;\n        b.value6823 = 6823;\n        b.value6824 = 6824;\n        b.value6825 = 6825;\n        b.value6826 = 6826;\n        b.value6827 = 6827;\n        b.value6828 = 6828;\n        b.value6829 = 6829;\n        b.value6830 = 6830;\n        b.value6831 = 6831;\n        b.value6832 = 6832;\n        b.value6833 = 6833;\n        b.value6834 = 6834;\n        b.value6835 = 6835;\n        b.value6836 = 6836;\n        b.value6837 = 6837;\n        b.value6838 = 6838;\n        b.value6839 = 6839;\n        b.value6840 = 6840;\n        b.value6841 = 6841;\n        b.value6842 = 6842;\n        b.value6843 = 6843;\n        b.value6844 = 6844;\n        b.value6845 = 6845;\n        b.value6846 = 6846;\n        b.value6847 = 6847;\n        b.value6848 = 6848;\n        b.value6849 = 6849;\n        b.value6850 = 6850;\n        b.value6851 = 6851;\n        b.value6852 = 6852;\n        b.value6853 = 6853;\n        b.value6854 = 6854;\n        b.value6855 = 6855;\n        b.value6856 = 6856;\n        b.value6857 = 6857;\n        b.value6858 = 6858;\n        b.value6859 = 6859;\n        b.value6860 = 6860;\n        b.value6861 = 6861;\n        b.value6862 = 6862;\n        b.value6863 = 6863;\n        b.value6864 = 6864;\n        b.value6865 = 6865;\n        b.value6866 = 6866;\n        b.value6867 = 6867;\n        b.value6868 = 6868;\n        b.value6869 = 6869;\n        b.value6870 = 6870;\n        b.value6871 = 6871;\n        b.value6872 = 6872;\n        b.value6873 = 6873;\n        b.value6874 = 6874;\n        b.value6875 = 6875;\n        b.value6876 = 6876;\n        b.value6877 = 6877;\n        b.value6878 = 6878;\n        b.value6879 = 6879;\n        b.value6880 = 6880;\n        b.value6881 = 6881;\n        b.value6882 = 6882;\n        b.value6883 = 6883;\n        b.value6884 = 6884;\n        b.value6885 = 6885;\n        b.value6886 = 6886;\n        b.value6887 = 6887;\n        b.value6888 = 6888;\n        b.value6889 = 6889;\n        b.value6890 = 6890;\n        b.value6891 = 6891;\n        b.value6892 = 6892;\n        b.value6893 = 6893;\n        b.value6894 = 6894;\n        b.value6895 = 6895;\n        b.value6896 = 6896;\n        b.value6897 = 6897;\n        b.value6898 = 6898;\n        b.value6899 = 6899;\n        b.value6900 = 6900;\n        b.value6901 = 6901;\n        b.value6902 = 6902;\n        b.value6903 = 6903;\n        b.value6904 = 6904;\n        b.value6905 = 6905;\n        b.value6906 = 6906;\n        b.value6907 = 6907;\n        b.value6908 = 6908;\n        b.value6909 = 6909;\n        b.value6910 = 6910;\n        b.value6911 = 6911;\n        b.value6912 = 6912;\n        b.value6913 = 6913;\n        b.value6914 = 6914;\n        b.value6915 = 6915;\n        b.value6916 = 6916;\n        b.value6917 = 6917;\n        b.value6918 = 6918;\n        b.value6919 = 6919;\n        b.value6920 = 6920;\n        b.value6921 = 6921;\n        b.value6922 = 6922;\n        b.value6923 = 6923;\n        b.value6924 = 6924;\n        b.value6925 = 6925;\n        b.value6926 = 6926;\n        b.value6927 = 6927;\n        b.value6928 = 6928;\n        b.value6929 = 6929;\n        b.value6930 = 6930;\n        b.value6931 = 6931;\n        b.value6932 = 6932;\n        b.value6933 = 6933;\n        b.value6934 = 6934;\n        b.value6935 = 6935;\n        b.value6936 = 6936;\n        b.value6937 = 6937;\n        b.value6938 = 6938;\n        b.value6939 = 6939;\n        b.value6940 = 6940;\n        b.value6941 = 6941;\n        b.value6942 = 6942;\n        b.value6943 = 6943;\n        b.value6944 = 6944;\n        b.value6945 = 6945;\n        b.value6946 = 6946;\n        b.value6947 = 6947;\n        b.value6948 = 6948;\n        b.value6949 = 6949;\n        b.value6950 = 6950;\n        b.value6951 = 6951;\n        b.value6952 = 6952;\n        b.value6953 = 6953;\n        b.value6954 = 6954;\n        b.value6955 = 6955;\n        b.value6956 = 6956;\n        b.value6957 = 6957;\n        b.value6958 = 6958;\n        b.value6959 = 6959;\n        b.value6960 = 6960;\n        b.value6961 = 6961;\n        b.value6962 = 6962;\n        b.value6963 = 6963;\n        b.value6964 = 6964;\n        b.value6965 = 6965;\n        b.value6966 = 6966;\n        b.value6967 = 6967;\n        b.value6968 = 6968;\n        b.value6969 = 6969;\n        b.value6970 = 6970;\n        b.value6971 = 6971;\n        b.value6972 = 6972;\n        b.value6973 = 6973;\n        b.value6974 = 6974;\n        b.value6975 = 6975;\n        b.value6976 = 6976;\n        b.value6977 = 6977;\n        b.value6978 = 6978;\n        b.value6979 = 6979;\n        b.value6980 = 6980;\n        b.value6981 = 6981;\n        b.value6982 = 6982;\n        b.value6983 = 6983;\n        b.value6984 = 6984;\n        b.value6985 = 6985;\n        b.value6986 = 6986;\n        b.value6987 = 6987;\n        b.value6988 = 6988;\n        b.value6989 = 6989;\n        b.value6990 = 6990;\n        b.value6991 = 6991;\n        b.value6992 = 6992;\n        b.value6993 = 6993;\n        b.value6994 = 6994;\n        b.value6995 = 6995;\n        b.value6996 = 6996;\n        b.value6997 = 6997;\n        b.value6998 = 6998;\n        b.value6999 = 6999;\n        b.value7000 = 7000;\n        b.value7001 = 7001;\n        b.value7002 = 7002;\n        b.value7003 = 7003;\n        b.value7004 = 7004;\n        b.value7005 = 7005;\n        b.value7006 = 7006;\n        b.value7007 = 7007;\n        b.value7008 = 7008;\n        b.value7009 = 7009;\n        b.value7010 = 7010;\n        b.value7011 = 7011;\n        b.value7012 = 7012;\n        b.value7013 = 7013;\n        b.value7014 = 7014;\n        b.value7015 = 7015;\n        b.value7016 = 7016;\n        b.value7017 = 7017;\n        b.value7018 = 7018;\n        b.value7019 = 7019;\n        b.value7020 = 7020;\n        b.value7021 = 7021;\n        b.value7022 = 7022;\n        b.value7023 = 7023;\n        b.value7024 = 7024;\n        b.value7025 = 7025;\n        b.value7026 = 7026;\n        b.value7027 = 7027;\n        b.value7028 = 7028;\n        b.value7029 = 7029;\n        b.value7030 = 7030;\n        b.value7031 = 7031;\n        b.value7032 = 7032;\n        b.value7033 = 7033;\n        b.value7034 = 7034;\n        b.value7035 = 7035;\n        b.value7036 = 7036;\n        b.value7037 = 7037;\n        b.value7038 = 7038;\n        b.value7039 = 7039;\n        b.value7040 = 7040;\n        b.value7041 = 7041;\n        b.value7042 = 7042;\n        b.value7043 = 7043;\n        b.value7044 = 7044;\n        b.value7045 = 7045;\n        b.value7046 = 7046;\n        b.value7047 = 7047;\n        b.value7048 = 7048;\n        b.value7049 = 7049;\n        b.value7050 = 7050;\n        b.value7051 = 7051;\n        b.value7052 = 7052;\n        b.value7053 = 7053;\n        b.value7054 = 7054;\n        b.value7055 = 7055;\n        b.value7056 = 7056;\n        b.value7057 = 7057;\n        b.value7058 = 7058;\n        b.value7059 = 7059;\n        b.value7060 = 7060;\n        b.value7061 = 7061;\n        b.value7062 = 7062;\n        b.value7063 = 7063;\n        b.value7064 = 7064;\n        b.value7065 = 7065;\n        b.value7066 = 7066;\n        b.value7067 = 7067;\n        b.value7068 = 7068;\n        b.value7069 = 7069;\n        b.value7070 = 7070;\n        b.value7071 = 7071;\n        b.value7072 = 7072;\n        b.value7073 = 7073;\n        b.value7074 = 7074;\n        b.value7075 = 7075;\n        b.value7076 = 7076;\n        b.value7077 = 7077;\n        b.value7078 = 7078;\n        b.value7079 = 7079;\n        b.value7080 = 7080;\n        b.value7081 = 7081;\n        b.value7082 = 7082;\n        b.value7083 = 7083;\n        b.value7084 = 7084;\n        b.value7085 = 7085;\n        b.value7086 = 7086;\n        b.value7087 = 7087;\n        b.value7088 = 7088;\n        b.value7089 = 7089;\n        b.value7090 = 7090;\n        b.value7091 = 7091;\n        b.value7092 = 7092;\n        b.value7093 = 7093;\n        b.value7094 = 7094;\n        b.value7095 = 7095;\n        b.value7096 = 7096;\n        b.value7097 = 7097;\n        b.value7098 = 7098;\n        b.value7099 = 7099;\n        b.value7100 = 7100;\n        b.value7101 = 7101;\n        b.value7102 = 7102;\n        b.value7103 = 7103;\n        b.value7104 = 7104;\n        b.value7105 = 7105;\n        b.value7106 = 7106;\n        b.value7107 = 7107;\n        b.value7108 = 7108;\n        b.value7109 = 7109;\n        b.value7110 = 7110;\n        b.value7111 = 7111;\n        b.value7112 = 7112;\n        b.value7113 = 7113;\n        b.value7114 = 7114;\n        b.value7115 = 7115;\n        b.value7116 = 7116;\n        b.value7117 = 7117;\n        b.value7118 = 7118;\n        b.value7119 = 7119;\n        b.value7120 = 7120;\n        b.value7121 = 7121;\n        b.value7122 = 7122;\n        b.value7123 = 7123;\n        b.value7124 = 7124;\n        b.value7125 = 7125;\n        b.value7126 = 7126;\n        b.value7127 = 7127;\n        b.value7128 = 7128;\n        b.value7129 = 7129;\n        b.value7130 = 7130;\n        b.value7131 = 7131;\n        b.value7132 = 7132;\n        b.value7133 = 7133;\n        b.value7134 = 7134;\n        b.value7135 = 7135;\n        b.value7136 = 7136;\n        b.value7137 = 7137;\n        b.value7138 = 7138;\n        b.value7139 = 7139;\n        b.value7140 = 7140;\n        b.value7141 = 7141;\n        b.value7142 = 7142;\n        b.value7143 = 7143;\n        b.value7144 = 7144;\n        b.value7145 = 7145;\n        b.value7146 = 7146;\n        b.value7147 = 7147;\n        b.value7148 = 7148;\n        b.value7149 = 7149;\n        b.value7150 = 7150;\n        b.value7151 = 7151;\n        b.value7152 = 7152;\n        b.value7153 = 7153;\n        b.value7154 = 7154;\n        b.value7155 = 7155;\n        b.value7156 = 7156;\n        b.value7157 = 7157;\n        b.value7158 = 7158;\n        b.value7159 = 7159;\n        b.value7160 = 7160;\n        b.value7161 = 7161;\n        b.value7162 = 7162;\n        b.value7163 = 7163;\n        b.value7164 = 7164;\n        b.value7165 = 7165;\n        b.value7166 = 7166;\n        b.value7167 = 7167;\n        b.value7168 = 7168;\n        b.value7169 = 7169;\n        b.value7170 = 7170;\n        b.value7171 = 7171;\n        b.value7172 = 7172;\n        b.value7173 = 7173;\n        b.value7174 = 7174;\n        b.value7175 = 7175;\n        b.value7176 = 7176;\n        b.value7177 = 7177;\n        b.value7178 = 7178;\n        b.value7179 = 7179;\n        b.value7180 = 7180;\n        b.value7181 = 7181;\n        b.value7182 = 7182;\n        b.value7183 = 7183;\n        b.value7184 = 7184;\n        b.value7185 = 7185;\n        b.value7186 = 7186;\n        b.value7187 = 7187;\n        b.value7188 = 7188;\n        b.value7189 = 7189;\n        b.value7190 = 7190;\n        b.value7191 = 7191;\n        b.value7192 = 7192;\n        b.value7193 = 7193;\n        b.value7194 = 7194;\n        b.value7195 = 7195;\n        b.value7196 = 7196;\n        b.value7197 = 7197;\n        b.value7198 = 7198;\n        b.value7199 = 7199;\n        b.value7200 = 7200;\n        b.value7201 = 7201;\n        b.value7202 = 7202;\n        b.value7203 = 7203;\n        b.value7204 = 7204;\n        b.value7205 = 7205;\n        b.value7206 = 7206;\n        b.value7207 = 7207;\n        b.value7208 = 7208;\n        b.value7209 = 7209;\n        b.value7210 = 7210;\n        b.value7211 = 7211;\n        b.value7212 = 7212;\n        b.value7213 = 7213;\n        b.value7214 = 7214;\n        b.value7215 = 7215;\n        b.value7216 = 7216;\n        b.value7217 = 7217;\n        b.value7218 = 7218;\n        b.value7219 = 7219;\n        b.value7220 = 7220;\n        b.value7221 = 7221;\n        b.value7222 = 7222;\n        b.value7223 = 7223;\n        b.value7224 = 7224;\n        b.value7225 = 7225;\n        b.value7226 = 7226;\n        b.value7227 = 7227;\n        b.value7228 = 7228;\n        b.value7229 = 7229;\n        b.value7230 = 7230;\n        b.value7231 = 7231;\n        b.value7232 = 7232;\n        b.value7233 = 7233;\n        b.value7234 = 7234;\n        b.value7235 = 7235;\n        b.value7236 = 7236;\n        b.value7237 = 7237;\n        b.value7238 = 7238;\n        b.value7239 = 7239;\n        b.value7240 = 7240;\n        b.value7241 = 7241;\n        b.value7242 = 7242;\n        b.value7243 = 7243;\n        b.value7244 = 7244;\n        b.value7245 = 7245;\n        b.value7246 = 7246;\n        b.value7247 = 7247;\n        b.value7248 = 7248;\n        b.value7249 = 7249;\n        b.value7250 = 7250;\n        b.value7251 = 7251;\n        b.value7252 = 7252;\n        b.value7253 = 7253;\n        b.value7254 = 7254;\n        b.value7255 = 7255;\n        b.value7256 = 7256;\n        b.value7257 = 7257;\n        b.value7258 = 7258;\n        b.value7259 = 7259;\n        b.value7260 = 7260;\n        b.value7261 = 7261;\n        b.value7262 = 7262;\n        b.value7263 = 7263;\n        b.value7264 = 7264;\n        b.value7265 = 7265;\n        b.value7266 = 7266;\n        b.value7267 = 7267;\n        b.value7268 = 7268;\n        b.value7269 = 7269;\n        b.value7270 = 7270;\n        b.value7271 = 7271;\n        b.value7272 = 7272;\n        b.value7273 = 7273;\n        b.value7274 = 7274;\n        b.value7275 = 7275;\n        b.value7276 = 7276;\n        b.value7277 = 7277;\n        b.value7278 = 7278;\n        b.value7279 = 7279;\n        b.value7280 = 7280;\n        b.value7281 = 7281;\n        b.value7282 = 7282;\n        b.value7283 = 7283;\n        b.value7284 = 7284;\n        b.value7285 = 7285;\n        b.value7286 = 7286;\n        b.value7287 = 7287;\n        b.value7288 = 7288;\n        b.value7289 = 7289;\n        b.value7290 = 7290;\n        b.value7291 = 7291;\n        b.value7292 = 7292;\n        b.value7293 = 7293;\n        b.value7294 = 7294;\n        b.value7295 = 7295;\n        b.value7296 = 7296;\n        b.value7297 = 7297;\n        b.value7298 = 7298;\n        b.value7299 = 7299;\n        b.value7300 = 7300;\n        b.value7301 = 7301;\n        b.value7302 = 7302;\n        b.value7303 = 7303;\n        b.value7304 = 7304;\n        b.value7305 = 7305;\n        b.value7306 = 7306;\n        b.value7307 = 7307;\n        b.value7308 = 7308;\n        b.value7309 = 7309;\n        b.value7310 = 7310;\n        b.value7311 = 7311;\n        b.value7312 = 7312;\n        b.value7313 = 7313;\n        b.value7314 = 7314;\n        b.value7315 = 7315;\n        b.value7316 = 7316;\n        b.value7317 = 7317;\n        b.value7318 = 7318;\n        b.value7319 = 7319;\n        b.value7320 = 7320;\n        b.value7321 = 7321;\n        b.value7322 = 7322;\n        b.value7323 = 7323;\n        b.value7324 = 7324;\n        b.value7325 = 7325;\n        b.value7326 = 7326;\n        b.value7327 = 7327;\n        b.value7328 = 7328;\n        b.value7329 = 7329;\n        b.value7330 = 7330;\n        b.value7331 = 7331;\n        b.value7332 = 7332;\n        b.value7333 = 7333;\n        b.value7334 = 7334;\n        b.value7335 = 7335;\n        b.value7336 = 7336;\n        b.value7337 = 7337;\n        b.value7338 = 7338;\n        b.value7339 = 7339;\n        b.value7340 = 7340;\n        b.value7341 = 7341;\n        b.value7342 = 7342;\n        b.value7343 = 7343;\n        b.value7344 = 7344;\n        b.value7345 = 7345;\n        b.value7346 = 7346;\n        b.value7347 = 7347;\n        b.value7348 = 7348;\n        b.value7349 = 7349;\n        b.value7350 = 7350;\n        b.value7351 = 7351;\n        b.value7352 = 7352;\n        b.value7353 = 7353;\n        b.value7354 = 7354;\n        b.value7355 = 7355;\n        b.value7356 = 7356;\n        b.value7357 = 7357;\n        b.value7358 = 7358;\n        b.value7359 = 7359;\n        b.value7360 = 7360;\n        b.value7361 = 7361;\n        b.value7362 = 7362;\n        b.value7363 = 7363;\n        b.value7364 = 7364;\n        b.value7365 = 7365;\n        b.value7366 = 7366;\n        b.value7367 = 7367;\n        b.value7368 = 7368;\n        b.value7369 = 7369;\n        b.value7370 = 7370;\n        b.value7371 = 7371;\n        b.value7372 = 7372;\n        b.value7373 = 7373;\n        b.value7374 = 7374;\n        b.value7375 = 7375;\n        b.value7376 = 7376;\n        b.value7377 = 7377;\n        b.value7378 = 7378;\n        b.value7379 = 7379;\n        b.value7380 = 7380;\n        b.value7381 = 7381;\n        b.value7382 = 7382;\n        b.value7383 = 7383;\n        b.value7384 = 7384;\n        b.value7385 = 7385;\n        b.value7386 = 7386;\n        b.value7387 = 7387;\n        b.value7388 = 7388;\n        b.value7389 = 7389;\n        b.value7390 = 7390;\n        b.value7391 = 7391;\n        b.value7392 = 7392;\n        b.value7393 = 7393;\n        b.value7394 = 7394;\n        b.value7395 = 7395;\n        b.value7396 = 7396;\n        b.value7397 = 7397;\n        b.value7398 = 7398;\n        b.value7399 = 7399;\n        b.value7400 = 7400;\n        b.value7401 = 7401;\n        b.value7402 = 7402;\n        b.value7403 = 7403;\n        b.value7404 = 7404;\n        b.value7405 = 7405;\n        b.value7406 = 7406;\n        b.value7407 = 7407;\n        b.value7408 = 7408;\n        b.value7409 = 7409;\n        b.value7410 = 7410;\n        b.value7411 = 7411;\n        b.value7412 = 7412;\n        b.value7413 = 7413;\n        b.value7414 = 7414;\n        b.value7415 = 7415;\n        b.value7416 = 7416;\n        b.value7417 = 7417;\n        b.value7418 = 7418;\n        b.value7419 = 7419;\n        b.value7420 = 7420;\n        b.value7421 = 7421;\n        b.value7422 = 7422;\n        b.value7423 = 7423;\n        b.value7424 = 7424;\n        b.value7425 = 7425;\n        b.value7426 = 7426;\n        b.value7427 = 7427;\n        b.value7428 = 7428;\n        b.value7429 = 7429;\n        b.value7430 = 7430;\n        b.value7431 = 7431;\n        b.value7432 = 7432;\n        b.value7433 = 7433;\n        b.value7434 = 7434;\n        b.value7435 = 7435;\n        b.value7436 = 7436;\n        b.value7437 = 7437;\n        b.value7438 = 7438;\n        b.value7439 = 7439;\n        b.value7440 = 7440;\n        b.value7441 = 7441;\n        b.value7442 = 7442;\n        b.value7443 = 7443;\n        b.value7444 = 7444;\n        b.value7445 = 7445;\n        b.value7446 = 7446;\n        b.value7447 = 7447;\n        b.value7448 = 7448;\n        b.value7449 = 7449;\n        b.value7450 = 7450;\n        b.value7451 = 7451;\n        b.value7452 = 7452;\n        b.value7453 = 7453;\n        b.value7454 = 7454;\n        b.value7455 = 7455;\n        b.value7456 = 7456;\n        b.value7457 = 7457;\n        b.value7458 = 7458;\n        b.value7459 = 7459;\n        b.value7460 = 7460;\n        b.value7461 = 7461;\n        b.value7462 = 7462;\n        b.value7463 = 7463;\n        b.value7464 = 7464;\n        b.value7465 = 7465;\n        b.value7466 = 7466;\n        b.value7467 = 7467;\n        b.value7468 = 7468;\n        b.value7469 = 7469;\n        b.value7470 = 7470;\n        b.value7471 = 7471;\n        b.value7472 = 7472;\n        b.value7473 = 7473;\n        b.value7474 = 7474;\n        b.value7475 = 7475;\n        b.value7476 = 7476;\n        b.value7477 = 7477;\n        b.value7478 = 7478;\n        b.value7479 = 7479;\n        b.value7480 = 7480;\n        b.value7481 = 7481;\n        b.value7482 = 7482;\n        b.value7483 = 7483;\n        b.value7484 = 7484;\n        b.value7485 = 7485;\n        b.value7486 = 7486;\n        b.value7487 = 7487;\n        b.value7488 = 7488;\n        b.value7489 = 7489;\n        b.value7490 = 7490;\n        b.value7491 = 7491;\n        b.value7492 = 7492;\n        b.value7493 = 7493;\n        b.value7494 = 7494;\n        b.value7495 = 7495;\n        b.value7496 = 7496;\n        b.value7497 = 7497;\n        b.value7498 = 7498;\n        b.value7499 = 7499;\n        b.value7500 = 7500;\n        b.value7501 = 7501;\n        b.value7502 = 7502;\n        b.value7503 = 7503;\n        b.value7504 = 7504;\n        b.value7505 = 7505;\n        b.value7506 = 7506;\n        b.value7507 = 7507;\n        b.value7508 = 7508;\n        b.value7509 = 7509;\n        b.value7510 = 7510;\n        b.value7511 = 7511;\n        b.value7512 = 7512;\n        b.value7513 = 7513;\n        b.value7514 = 7514;\n        b.value7515 = 7515;\n        b.value7516 = 7516;\n        b.value7517 = 7517;\n        b.value7518 = 7518;\n        b.value7519 = 7519;\n        b.value7520 = 7520;\n        b.value7521 = 7521;\n        b.value7522 = 7522;\n        b.value7523 = 7523;\n        b.value7524 = 7524;\n        b.value7525 = 7525;\n        b.value7526 = 7526;\n        b.value7527 = 7527;\n        b.value7528 = 7528;\n        b.value7529 = 7529;\n        b.value7530 = 7530;\n        b.value7531 = 7531;\n        b.value7532 = 7532;\n        b.value7533 = 7533;\n        b.value7534 = 7534;\n        b.value7535 = 7535;\n        b.value7536 = 7536;\n        b.value7537 = 7537;\n        b.value7538 = 7538;\n        b.value7539 = 7539;\n        b.value7540 = 7540;\n        b.value7541 = 7541;\n        b.value7542 = 7542;\n        b.value7543 = 7543;\n        b.value7544 = 7544;\n        b.value7545 = 7545;\n        b.value7546 = 7546;\n        b.value7547 = 7547;\n        b.value7548 = 7548;\n        b.value7549 = 7549;\n        b.value7550 = 7550;\n        b.value7551 = 7551;\n        b.value7552 = 7552;\n        b.value7553 = 7553;\n        b.value7554 = 7554;\n        b.value7555 = 7555;\n        b.value7556 = 7556;\n        b.value7557 = 7557;\n        b.value7558 = 7558;\n        b.value7559 = 7559;\n        b.value7560 = 7560;\n        b.value7561 = 7561;\n        b.value7562 = 7562;\n        b.value7563 = 7563;\n        b.value7564 = 7564;\n        b.value7565 = 7565;\n        b.value7566 = 7566;\n        b.value7567 = 7567;\n        b.value7568 = 7568;\n        b.value7569 = 7569;\n        b.value7570 = 7570;\n        b.value7571 = 7571;\n        b.value7572 = 7572;\n        b.value7573 = 7573;\n        b.value7574 = 7574;\n        b.value7575 = 7575;\n        b.value7576 = 7576;\n        b.value7577 = 7577;\n        b.value7578 = 7578;\n        b.value7579 = 7579;\n        b.value7580 = 7580;\n        b.value7581 = 7581;\n        b.value7582 = 7582;\n        b.value7583 = 7583;\n        b.value7584 = 7584;\n        b.value7585 = 7585;\n        b.value7586 = 7586;\n        b.value7587 = 7587;\n        b.value7588 = 7588;\n        b.value7589 = 7589;\n        b.value7590 = 7590;\n        b.value7591 = 7591;\n        b.value7592 = 7592;\n        b.value7593 = 7593;\n        b.value7594 = 7594;\n        b.value7595 = 7595;\n        b.value7596 = 7596;\n        b.value7597 = 7597;\n        b.value7598 = 7598;\n        b.value7599 = 7599;\n        b.value7600 = 7600;\n        b.value7601 = 7601;\n        b.value7602 = 7602;\n        b.value7603 = 7603;\n        b.value7604 = 7604;\n        b.value7605 = 7605;\n        b.value7606 = 7606;\n        b.value7607 = 7607;\n        b.value7608 = 7608;\n        b.value7609 = 7609;\n        b.value7610 = 7610;\n        b.value7611 = 7611;\n        b.value7612 = 7612;\n        b.value7613 = 7613;\n        b.value7614 = 7614;\n        b.value7615 = 7615;\n        b.value7616 = 7616;\n        b.value7617 = 7617;\n        b.value7618 = 7618;\n        b.value7619 = 7619;\n        b.value7620 = 7620;\n        b.value7621 = 7621;\n        b.value7622 = 7622;\n        b.value7623 = 7623;\n        b.value7624 = 7624;\n        b.value7625 = 7625;\n        b.value7626 = 7626;\n        b.value7627 = 7627;\n        b.value7628 = 7628;\n        b.value7629 = 7629;\n        b.value7630 = 7630;\n        b.value7631 = 7631;\n        b.value7632 = 7632;\n        b.value7633 = 7633;\n        b.value7634 = 7634;\n        b.value7635 = 7635;\n        b.value7636 = 7636;\n        b.value7637 = 7637;\n        b.value7638 = 7638;\n        b.value7639 = 7639;\n        b.value7640 = 7640;\n        b.value7641 = 7641;\n        b.value7642 = 7642;\n        b.value7643 = 7643;\n        b.value7644 = 7644;\n        b.value7645 = 7645;\n        b.value7646 = 7646;\n        b.value7647 = 7647;\n        b.value7648 = 7648;\n        b.value7649 = 7649;\n        b.value7650 = 7650;\n        b.value7651 = 7651;\n        b.value7652 = 7652;\n        b.value7653 = 7653;\n        b.value7654 = 7654;\n        b.value7655 = 7655;\n        b.value7656 = 7656;\n        b.value7657 = 7657;\n        b.value7658 = 7658;\n        b.value7659 = 7659;\n        b.value7660 = 7660;\n        b.value7661 = 7661;\n        b.value7662 = 7662;\n        b.value7663 = 7663;\n        b.value7664 = 7664;\n        b.value7665 = 7665;\n        b.value7666 = 7666;\n        b.value7667 = 7667;\n        b.value7668 = 7668;\n        b.value7669 = 7669;\n        b.value7670 = 7670;\n        b.value7671 = 7671;\n        b.value7672 = 7672;\n        b.value7673 = 7673;\n        b.value7674 = 7674;\n        b.value7675 = 7675;\n        b.value7676 = 7676;\n        b.value7677 = 7677;\n        b.value7678 = 7678;\n        b.value7679 = 7679;\n        b.value7680 = 7680;\n        b.value7681 = 7681;\n        b.value7682 = 7682;\n        b.value7683 = 7683;\n        b.value7684 = 7684;\n        b.value7685 = 7685;\n        b.value7686 = 7686;\n        b.value7687 = 7687;\n        b.value7688 = 7688;\n        b.value7689 = 7689;\n        b.value7690 = 7690;\n        b.value7691 = 7691;\n        b.value7692 = 7692;\n        b.value7693 = 7693;\n        b.value7694 = 7694;\n        b.value7695 = 7695;\n        b.value7696 = 7696;\n        b.value7697 = 7697;\n        b.value7698 = 7698;\n        b.value7699 = 7699;\n        b.value7700 = 7700;\n        b.value7701 = 7701;\n        b.value7702 = 7702;\n        b.value7703 = 7703;\n        b.value7704 = 7704;\n        b.value7705 = 7705;\n        b.value7706 = 7706;\n        b.value7707 = 7707;\n        b.value7708 = 7708;\n        b.value7709 = 7709;\n        b.value7710 = 7710;\n        b.value7711 = 7711;\n        b.value7712 = 7712;\n        b.value7713 = 7713;\n        b.value7714 = 7714;\n        b.value7715 = 7715;\n        b.value7716 = 7716;\n        b.value7717 = 7717;\n        b.value7718 = 7718;\n        b.value7719 = 7719;\n        b.value7720 = 7720;\n        b.value7721 = 7721;\n        b.value7722 = 7722;\n        b.value7723 = 7723;\n        b.value7724 = 7724;\n        b.value7725 = 7725;\n        b.value7726 = 7726;\n        b.value7727 = 7727;\n        b.value7728 = 7728;\n        b.value7729 = 7729;\n        b.value7730 = 7730;\n        b.value7731 = 7731;\n        b.value7732 = 7732;\n        b.value7733 = 7733;\n        b.value7734 = 7734;\n        b.value7735 = 7735;\n        b.value7736 = 7736;\n        b.value7737 = 7737;\n        b.value7738 = 7738;\n        b.value7739 = 7739;\n        b.value7740 = 7740;\n        b.value7741 = 7741;\n        b.value7742 = 7742;\n        b.value7743 = 7743;\n        b.value7744 = 7744;\n        b.value7745 = 7745;\n        b.value7746 = 7746;\n        b.value7747 = 7747;\n        b.value7748 = 7748;\n        b.value7749 = 7749;\n        b.value7750 = 7750;\n        b.value7751 = 7751;\n        b.value7752 = 7752;\n        b.value7753 = 7753;\n        b.value7754 = 7754;\n        b.value7755 = 7755;\n        b.value7756 = 7756;\n        b.value7757 = 7757;\n        b.value7758 = 7758;\n        b.value7759 = 7759;\n        b.value7760 = 7760;\n        b.value7761 = 7761;\n        b.value7762 = 7762;\n        b.value7763 = 7763;\n        b.value7764 = 7764;\n        b.value7765 = 7765;\n        b.value7766 = 7766;\n        b.value7767 = 7767;\n        b.value7768 = 7768;\n        b.value7769 = 7769;\n        b.value7770 = 7770;\n        b.value7771 = 7771;\n        b.value7772 = 7772;\n        b.value7773 = 7773;\n        b.value7774 = 7774;\n        b.value7775 = 7775;\n        b.value7776 = 7776;\n        b.value7777 = 7777;\n        this.b = b;\n    }\n    # no need for teardown since we recreate the list each time\n\n    func test() {\n        for i in 0.to(50) {\n            val b = this.b;\n            foo(b.value0);\n            foo(b.value1);\n            foo(b.value2);\n            foo(b.value3);\n            foo(b.value4);\n            foo(b.value5);\n            foo(b.value6);\n            foo(b.value7);\n            foo(b.value8);\n            foo(b.value9);\n            foo(b.value10);\n            foo(b.value11);\n            foo(b.value12);\n            foo(b.value13);\n            foo(b.value14);\n            foo(b.value15);\n            foo(b.value16);\n            foo(b.value17);\n            foo(b.value18);\n            foo(b.value19);\n            foo(b.value20);\n            foo(b.value21);\n            foo(b.value22);\n            foo(b.value23);\n            foo(b.value24);\n            foo(b.value25);\n            foo(b.value26);\n            foo(b.value27);\n            foo(b.value28);\n            foo(b.value29);\n            foo(b.value30);\n            foo(b.value31);\n            foo(b.value32);\n            foo(b.value33);\n            foo(b.value34);\n            foo(b.value35);\n            foo(b.value36);\n            foo(b.value37);\n            foo(b.value38);\n            foo(b.value39);\n            foo(b.value40);\n            foo(b.value41);\n            foo(b.value42);\n            foo(b.value43);\n            foo(b.value44);\n            foo(b.value45);\n            foo(b.value46);\n            foo(b.value47);\n            foo(b.value48);\n            foo(b.value49);\n            foo(b.value50);\n            foo(b.value51);\n            foo(b.value52);\n            foo(b.value53);\n            foo(b.value54);\n            foo(b.value55);\n            foo(b.value56);\n            foo(b.value57);\n            foo(b.value58);\n            foo(b.value59);\n            foo(b.value60);\n            foo(b.value61);\n            foo(b.value62);\n            foo(b.value63);\n            foo(b.value64);\n            foo(b.value65);\n            foo(b.value66);\n            foo(b.value67);\n            foo(b.value68);\n            foo(b.value69);\n            foo(b.value70);\n            foo(b.value71);\n            foo(b.value72);\n            foo(b.value73);\n            foo(b.value74);\n            foo(b.value75);\n            foo(b.value76);\n            foo(b.value77);\n            foo(b.value78);\n            foo(b.value79);\n            foo(b.value80);\n            foo(b.value81);\n            foo(b.value82);\n            foo(b.value83);\n            foo(b.value84);\n            foo(b.value85);\n            foo(b.value86);\n            foo(b.value87);\n            foo(b.value88);\n            foo(b.value89);\n            foo(b.value90);\n            foo(b.value91);\n            foo(b.value92);\n            foo(b.value93);\n            foo(b.value94);\n            foo(b.value95);\n            foo(b.value96);\n            foo(b.value97);\n            foo(b.value98);\n            foo(b.value99);\n            foo(b.value100);\n            foo(b.value101);\n            foo(b.value102);\n            foo(b.value103);\n            foo(b.value104);\n            foo(b.value105);\n            foo(b.value106);\n            foo(b.value107);\n            foo(b.value108);\n            foo(b.value109);\n            foo(b.value110);\n            foo(b.value111);\n            foo(b.value112);\n            foo(b.value113);\n            foo(b.value114);\n            foo(b.value115);\n            foo(b.value116);\n            foo(b.value117);\n            foo(b.value118);\n            foo(b.value119);\n            foo(b.value120);\n            foo(b.value121);\n            foo(b.value122);\n            foo(b.value123);\n            foo(b.value124);\n            foo(b.value125);\n            foo(b.value126);\n            foo(b.value127);\n            foo(b.value128);\n            foo(b.value129);\n            foo(b.value130);\n            foo(b.value131);\n            foo(b.value132);\n            foo(b.value133);\n            foo(b.value134);\n            foo(b.value135);\n            foo(b.value136);\n            foo(b.value137);\n            foo(b.value138);\n            foo(b.value139);\n            foo(b.value140);\n            foo(b.value141);\n            foo(b.value142);\n            foo(b.value143);\n            foo(b.value144);\n            foo(b.value145);\n            foo(b.value146);\n            foo(b.value147);\n            foo(b.value148);\n            foo(b.value149);\n            foo(b.value150);\n            foo(b.value151);\n            foo(b.value152);\n            foo(b.value153);\n            foo(b.value154);\n            foo(b.value155);\n            foo(b.value156);\n            foo(b.value157);\n            foo(b.value158);\n            foo(b.value159);\n            foo(b.value160);\n            foo(b.value161);\n            foo(b.value162);\n            foo(b.value163);\n            foo(b.value164);\n            foo(b.value165);\n            foo(b.value166);\n            foo(b.value167);\n            foo(b.value168);\n            foo(b.value169);\n            foo(b.value170);\n            foo(b.value171);\n            foo(b.value172);\n            foo(b.value173);\n            foo(b.value174);\n            foo(b.value175);\n            foo(b.value176);\n            foo(b.value177);\n            foo(b.value178);\n            foo(b.value179);\n            foo(b.value180);\n            foo(b.value181);\n            foo(b.value182);\n            foo(b.value183);\n            foo(b.value184);\n            foo(b.value185);\n            foo(b.value186);\n            foo(b.value187);\n            foo(b.value188);\n            foo(b.value189);\n            foo(b.value190);\n            foo(b.value191);\n            foo(b.value192);\n            foo(b.value193);\n            foo(b.value194);\n            foo(b.value195);\n            foo(b.value196);\n            foo(b.value197);\n            foo(b.value198);\n            foo(b.value199);\n            foo(b.value200);\n            foo(b.value201);\n            foo(b.value202);\n            foo(b.value203);\n            foo(b.value204);\n            foo(b.value205);\n            foo(b.value206);\n            foo(b.value207);\n            foo(b.value208);\n            foo(b.value209);\n            foo(b.value210);\n            foo(b.value211);\n            foo(b.value212);\n            foo(b.value213);\n            foo(b.value214);\n            foo(b.value215);\n            foo(b.value216);\n            foo(b.value217);\n            foo(b.value218);\n            foo(b.value219);\n            foo(b.value220);\n            foo(b.value221);\n            foo(b.value222);\n            foo(b.value223);\n            foo(b.value224);\n            foo(b.value225);\n            foo(b.value226);\n            foo(b.value227);\n            foo(b.value228);\n            foo(b.value229);\n            foo(b.value230);\n            foo(b.value231);\n            foo(b.value232);\n            foo(b.value233);\n            foo(b.value234);\n            foo(b.value235);\n            foo(b.value236);\n            foo(b.value237);\n            foo(b.value238);\n            foo(b.value239);\n            foo(b.value240);\n            foo(b.value241);\n            foo(b.value242);\n            foo(b.value243);\n            foo(b.value244);\n            foo(b.value245);\n            foo(b.value246);\n            foo(b.value247);\n            foo(b.value248);\n            foo(b.value249);\n            foo(b.value250);\n            foo(b.value251);\n            foo(b.value252);\n            foo(b.value253);\n            foo(b.value254);\n            foo(b.value255);\n            foo(b.value256);\n            foo(b.value257);\n            foo(b.value258);\n            foo(b.value259);\n            foo(b.value260);\n            foo(b.value261);\n            foo(b.value262);\n            foo(b.value263);\n            foo(b.value264);\n            foo(b.value265);\n            foo(b.value266);\n            foo(b.value267);\n            foo(b.value268);\n            foo(b.value269);\n            foo(b.value270);\n            foo(b.value271);\n            foo(b.value272);\n            foo(b.value273);\n            foo(b.value274);\n            foo(b.value275);\n            foo(b.value276);\n            foo(b.value277);\n            foo(b.value278);\n            foo(b.value279);\n            foo(b.value280);\n            foo(b.value281);\n            foo(b.value282);\n            foo(b.value283);\n            foo(b.value284);\n            foo(b.value285);\n            foo(b.value286);\n            foo(b.value287);\n            foo(b.value288);\n            foo(b.value289);\n            foo(b.value290);\n            foo(b.value291);\n            foo(b.value292);\n            foo(b.value293);\n            foo(b.value294);\n            foo(b.value295);\n            foo(b.value296);\n            foo(b.value297);\n            foo(b.value298);\n            foo(b.value299);\n            foo(b.value300);\n            foo(b.value301);\n            foo(b.value302);\n            foo(b.value303);\n            foo(b.value304);\n            foo(b.value305);\n            foo(b.value306);\n            foo(b.value307);\n            foo(b.value308);\n            foo(b.value309);\n            foo(b.value310);\n            foo(b.value311);\n            foo(b.value312);\n            foo(b.value313);\n            foo(b.value314);\n            foo(b.value315);\n            foo(b.value316);\n            foo(b.value317);\n            foo(b.value318);\n            foo(b.value319);\n            foo(b.value320);\n            foo(b.value321);\n            foo(b.value322);\n            foo(b.value323);\n            foo(b.value324);\n            foo(b.value325);\n            foo(b.value326);\n            foo(b.value327);\n            foo(b.value328);\n            foo(b.value329);\n            foo(b.value330);\n            foo(b.value331);\n            foo(b.value332);\n            foo(b.value333);\n            foo(b.value334);\n            foo(b.value335);\n            foo(b.value336);\n            foo(b.value337);\n            foo(b.value338);\n            foo(b.value339);\n            foo(b.value340);\n            foo(b.value341);\n            foo(b.value342);\n            foo(b.value343);\n            foo(b.value344);\n            foo(b.value345);\n            foo(b.value346);\n            foo(b.value347);\n            foo(b.value348);\n            foo(b.value349);\n            foo(b.value350);\n            foo(b.value351);\n            foo(b.value352);\n            foo(b.value353);\n            foo(b.value354);\n            foo(b.value355);\n            foo(b.value356);\n            foo(b.value357);\n            foo(b.value358);\n            foo(b.value359);\n            foo(b.value360);\n            foo(b.value361);\n            foo(b.value362);\n            foo(b.value363);\n            foo(b.value364);\n            foo(b.value365);\n            foo(b.value366);\n            foo(b.value367);\n            foo(b.value368);\n            foo(b.value369);\n            foo(b.value370);\n            foo(b.value371);\n            foo(b.value372);\n            foo(b.value373);\n            foo(b.value374);\n            foo(b.value375);\n            foo(b.value376);\n            foo(b.value377);\n            foo(b.value378);\n            foo(b.value379);\n            foo(b.value380);\n            foo(b.value381);\n            foo(b.value382);\n            foo(b.value383);\n            foo(b.value384);\n            foo(b.value385);\n            foo(b.value386);\n            foo(b.value387);\n            foo(b.value388);\n            foo(b.value389);\n            foo(b.value390);\n            foo(b.value391);\n            foo(b.value392);\n            foo(b.value393);\n            foo(b.value394);\n            foo(b.value395);\n            foo(b.value396);\n            foo(b.value397);\n            foo(b.value398);\n            foo(b.value399);\n            foo(b.value400);\n            foo(b.value401);\n            foo(b.value402);\n            foo(b.value403);\n            foo(b.value404);\n            foo(b.value405);\n            foo(b.value406);\n            foo(b.value407);\n            foo(b.value408);\n            foo(b.value409);\n            foo(b.value410);\n            foo(b.value411);\n            foo(b.value412);\n            foo(b.value413);\n            foo(b.value414);\n            foo(b.value415);\n            foo(b.value416);\n            foo(b.value417);\n            foo(b.value418);\n            foo(b.value419);\n            foo(b.value420);\n            foo(b.value421);\n            foo(b.value422);\n            foo(b.value423);\n            foo(b.value424);\n            foo(b.value425);\n            foo(b.value426);\n            foo(b.value427);\n            foo(b.value428);\n            foo(b.value429);\n            foo(b.value430);\n            foo(b.value431);\n            foo(b.value432);\n            foo(b.value433);\n            foo(b.value434);\n            foo(b.value435);\n            foo(b.value436);\n            foo(b.value437);\n            foo(b.value438);\n            foo(b.value439);\n            foo(b.value440);\n            foo(b.value441);\n            foo(b.value442);\n            foo(b.value443);\n            foo(b.value444);\n            foo(b.value445);\n            foo(b.value446);\n            foo(b.value447);\n            foo(b.value448);\n            foo(b.value449);\n            foo(b.value450);\n            foo(b.value451);\n            foo(b.value452);\n            foo(b.value453);\n            foo(b.value454);\n            foo(b.value455);\n            foo(b.value456);\n            foo(b.value457);\n            foo(b.value458);\n            foo(b.value459);\n            foo(b.value460);\n            foo(b.value461);\n            foo(b.value462);\n            foo(b.value463);\n            foo(b.value464);\n            foo(b.value465);\n            foo(b.value466);\n            foo(b.value467);\n            foo(b.value468);\n            foo(b.value469);\n            foo(b.value470);\n            foo(b.value471);\n            foo(b.value472);\n            foo(b.value473);\n            foo(b.value474);\n            foo(b.value475);\n            foo(b.value476);\n            foo(b.value477);\n            foo(b.value478);\n            foo(b.value479);\n            foo(b.value480);\n            foo(b.value481);\n            foo(b.value482);\n            foo(b.value483);\n            foo(b.value484);\n            foo(b.value485);\n            foo(b.value486);\n            foo(b.value487);\n            foo(b.value488);\n            foo(b.value489);\n            foo(b.value490);\n            foo(b.value491);\n            foo(b.value492);\n            foo(b.value493);\n            foo(b.value494);\n            foo(b.value495);\n            foo(b.value496);\n            foo(b.value497);\n            foo(b.value498);\n            foo(b.value499);\n            foo(b.value500);\n            foo(b.value501);\n            foo(b.value502);\n            foo(b.value503);\n            foo(b.value504);\n            foo(b.value505);\n            foo(b.value506);\n            foo(b.value507);\n            foo(b.value508);\n            foo(b.value509);\n            foo(b.value510);\n            foo(b.value511);\n            foo(b.value512);\n            foo(b.value513);\n            foo(b.value514);\n            foo(b.value515);\n            foo(b.value516);\n            foo(b.value517);\n            foo(b.value518);\n            foo(b.value519);\n            foo(b.value520);\n            foo(b.value521);\n            foo(b.value522);\n            foo(b.value523);\n            foo(b.value524);\n            foo(b.value525);\n            foo(b.value526);\n            foo(b.value527);\n            foo(b.value528);\n            foo(b.value529);\n            foo(b.value530);\n            foo(b.value531);\n            foo(b.value532);\n            foo(b.value533);\n            foo(b.value534);\n            foo(b.value535);\n            foo(b.value536);\n            foo(b.value537);\n            foo(b.value538);\n            foo(b.value539);\n            foo(b.value540);\n            foo(b.value541);\n            foo(b.value542);\n            foo(b.value543);\n            foo(b.value544);\n            foo(b.value545);\n            foo(b.value546);\n            foo(b.value547);\n            foo(b.value548);\n            foo(b.value549);\n            foo(b.value550);\n            foo(b.value551);\n            foo(b.value552);\n            foo(b.value553);\n            foo(b.value554);\n            foo(b.value555);\n            foo(b.value556);\n            foo(b.value557);\n            foo(b.value558);\n            foo(b.value559);\n            foo(b.value560);\n            foo(b.value561);\n            foo(b.value562);\n            foo(b.value563);\n            foo(b.value564);\n            foo(b.value565);\n            foo(b.value566);\n            foo(b.value567);\n            foo(b.value568);\n            foo(b.value569);\n            foo(b.value570);\n            foo(b.value571);\n            foo(b.value572);\n            foo(b.value573);\n            foo(b.value574);\n            foo(b.value575);\n            foo(b.value576);\n            foo(b.value577);\n            foo(b.value578);\n            foo(b.value579);\n            foo(b.value580);\n            foo(b.value581);\n            foo(b.value582);\n            foo(b.value583);\n            foo(b.value584);\n            foo(b.value585);\n            foo(b.value586);\n            foo(b.value587);\n            foo(b.value588);\n            foo(b.value589);\n            foo(b.value590);\n            foo(b.value591);\n            foo(b.value592);\n            foo(b.value593);\n            foo(b.value594);\n            foo(b.value595);\n            foo(b.value596);\n            foo(b.value597);\n            foo(b.value598);\n            foo(b.value599);\n            foo(b.value600);\n            foo(b.value601);\n            foo(b.value602);\n            foo(b.value603);\n            foo(b.value604);\n            foo(b.value605);\n            foo(b.value606);\n            foo(b.value607);\n            foo(b.value608);\n            foo(b.value609);\n            foo(b.value610);\n            foo(b.value611);\n            foo(b.value612);\n            foo(b.value613);\n            foo(b.value614);\n            foo(b.value615);\n            foo(b.value616);\n            foo(b.value617);\n            foo(b.value618);\n            foo(b.value619);\n            foo(b.value620);\n            foo(b.value621);\n            foo(b.value622);\n            foo(b.value623);\n            foo(b.value624);\n            foo(b.value625);\n            foo(b.value626);\n            foo(b.value627);\n            foo(b.value628);\n            foo(b.value629);\n            foo(b.value630);\n            foo(b.value631);\n            foo(b.value632);\n            foo(b.value633);\n            foo(b.value634);\n            foo(b.value635);\n            foo(b.value636);\n            foo(b.value637);\n            foo(b.value638);\n            foo(b.value639);\n            foo(b.value640);\n            foo(b.value641);\n            foo(b.value642);\n            foo(b.value643);\n            foo(b.value644);\n            foo(b.value645);\n            foo(b.value646);\n            foo(b.value647);\n            foo(b.value648);\n            foo(b.value649);\n            foo(b.value650);\n            foo(b.value651);\n            foo(b.value652);\n            foo(b.value653);\n            foo(b.value654);\n            foo(b.value655);\n            foo(b.value656);\n            foo(b.value657);\n            foo(b.value658);\n            foo(b.value659);\n            foo(b.value660);\n            foo(b.value661);\n            foo(b.value662);\n            foo(b.value663);\n            foo(b.value664);\n            foo(b.value665);\n            foo(b.value666);\n            foo(b.value667);\n            foo(b.value668);\n            foo(b.value669);\n            foo(b.value670);\n            foo(b.value671);\n            foo(b.value672);\n            foo(b.value673);\n            foo(b.value674);\n            foo(b.value675);\n            foo(b.value676);\n            foo(b.value677);\n            foo(b.value678);\n            foo(b.value679);\n            foo(b.value680);\n            foo(b.value681);\n            foo(b.value682);\n            foo(b.value683);\n            foo(b.value684);\n            foo(b.value685);\n            foo(b.value686);\n            foo(b.value687);\n            foo(b.value688);\n            foo(b.value689);\n            foo(b.value690);\n            foo(b.value691);\n            foo(b.value692);\n            foo(b.value693);\n            foo(b.value694);\n            foo(b.value695);\n            foo(b.value696);\n            foo(b.value697);\n            foo(b.value698);\n            foo(b.value699);\n            foo(b.value700);\n            foo(b.value701);\n            foo(b.value702);\n            foo(b.value703);\n            foo(b.value704);\n            foo(b.value705);\n            foo(b.value706);\n            foo(b.value707);\n            foo(b.value708);\n            foo(b.value709);\n            foo(b.value710);\n            foo(b.value711);\n            foo(b.value712);\n            foo(b.value713);\n            foo(b.value714);\n            foo(b.value715);\n            foo(b.value716);\n            foo(b.value717);\n            foo(b.value718);\n            foo(b.value719);\n            foo(b.value720);\n            foo(b.value721);\n            foo(b.value722);\n            foo(b.value723);\n            foo(b.value724);\n            foo(b.value725);\n            foo(b.value726);\n            foo(b.value727);\n            foo(b.value728);\n            foo(b.value729);\n            foo(b.value730);\n            foo(b.value731);\n            foo(b.value732);\n            foo(b.value733);\n            foo(b.value734);\n            foo(b.value735);\n            foo(b.value736);\n            foo(b.value737);\n            foo(b.value738);\n            foo(b.value739);\n            foo(b.value740);\n            foo(b.value741);\n            foo(b.value742);\n            foo(b.value743);\n            foo(b.value744);\n            foo(b.value745);\n            foo(b.value746);\n            foo(b.value747);\n            foo(b.value748);\n            foo(b.value749);\n            foo(b.value750);\n            foo(b.value751);\n            foo(b.value752);\n            foo(b.value753);\n            foo(b.value754);\n            foo(b.value755);\n            foo(b.value756);\n            foo(b.value757);\n            foo(b.value758);\n            foo(b.value759);\n            foo(b.value760);\n            foo(b.value761);\n            foo(b.value762);\n            foo(b.value763);\n            foo(b.value764);\n            foo(b.value765);\n            foo(b.value766);\n            foo(b.value767);\n            foo(b.value768);\n            foo(b.value769);\n            foo(b.value770);\n            foo(b.value771);\n            foo(b.value772);\n            foo(b.value773);\n            foo(b.value774);\n            foo(b.value775);\n            foo(b.value776);\n            foo(b.value777);\n            foo(b.value778);\n            foo(b.value779);\n            foo(b.value780);\n            foo(b.value781);\n            foo(b.value782);\n            foo(b.value783);\n            foo(b.value784);\n            foo(b.value785);\n            foo(b.value786);\n            foo(b.value787);\n            foo(b.value788);\n            foo(b.value789);\n            foo(b.value790);\n            foo(b.value791);\n            foo(b.value792);\n            foo(b.value793);\n            foo(b.value794);\n            foo(b.value795);\n            foo(b.value796);\n            foo(b.value797);\n            foo(b.value798);\n            foo(b.value799);\n            foo(b.value800);\n            foo(b.value801);\n            foo(b.value802);\n            foo(b.value803);\n            foo(b.value804);\n            foo(b.value805);\n            foo(b.value806);\n            foo(b.value807);\n            foo(b.value808);\n            foo(b.value809);\n            foo(b.value810);\n            foo(b.value811);\n            foo(b.value812);\n            foo(b.value813);\n            foo(b.value814);\n            foo(b.value815);\n            foo(b.value816);\n            foo(b.value817);\n            foo(b.value818);\n            foo(b.value819);\n            foo(b.value820);\n            foo(b.value821);\n            foo(b.value822);\n            foo(b.value823);\n            foo(b.value824);\n            foo(b.value825);\n            foo(b.value826);\n            foo(b.value827);\n            foo(b.value828);\n            foo(b.value829);\n            foo(b.value830);\n            foo(b.value831);\n            foo(b.value832);\n            foo(b.value833);\n            foo(b.value834);\n            foo(b.value835);\n            foo(b.value836);\n            foo(b.value837);\n            foo(b.value838);\n            foo(b.value839);\n            foo(b.value840);\n            foo(b.value841);\n            foo(b.value842);\n            foo(b.value843);\n            foo(b.value844);\n            foo(b.value845);\n            foo(b.value846);\n            foo(b.value847);\n            foo(b.value848);\n            foo(b.value849);\n            foo(b.value850);\n            foo(b.value851);\n            foo(b.value852);\n            foo(b.value853);\n            foo(b.value854);\n            foo(b.value855);\n            foo(b.value856);\n            foo(b.value857);\n            foo(b.value858);\n            foo(b.value859);\n            foo(b.value860);\n            foo(b.value861);\n            foo(b.value862);\n            foo(b.value863);\n            foo(b.value864);\n            foo(b.value865);\n            foo(b.value866);\n            foo(b.value867);\n            foo(b.value868);\n            foo(b.value869);\n            foo(b.value870);\n            foo(b.value871);\n            foo(b.value872);\n            foo(b.value873);\n            foo(b.value874);\n            foo(b.value875);\n            foo(b.value876);\n            foo(b.value877);\n            foo(b.value878);\n            foo(b.value879);\n            foo(b.value880);\n            foo(b.value881);\n            foo(b.value882);\n            foo(b.value883);\n            foo(b.value884);\n            foo(b.value885);\n            foo(b.value886);\n            foo(b.value887);\n            foo(b.value888);\n            foo(b.value889);\n            foo(b.value890);\n            foo(b.value891);\n            foo(b.value892);\n            foo(b.value893);\n            foo(b.value894);\n            foo(b.value895);\n            foo(b.value896);\n            foo(b.value897);\n            foo(b.value898);\n            foo(b.value899);\n            foo(b.value900);\n            foo(b.value901);\n            foo(b.value902);\n            foo(b.value903);\n            foo(b.value904);\n            foo(b.value905);\n            foo(b.value906);\n            foo(b.value907);\n            foo(b.value908);\n            foo(b.value909);\n            foo(b.value910);\n            foo(b.value911);\n            foo(b.value912);\n            foo(b.value913);\n            foo(b.value914);\n            foo(b.value915);\n            foo(b.value916);\n            foo(b.value917);\n            foo(b.value918);\n            foo(b.value919);\n            foo(b.value920);\n            foo(b.value921);\n            foo(b.value922);\n            foo(b.value923);\n            foo(b.value924);\n            foo(b.value925);\n            foo(b.value926);\n            foo(b.value927);\n            foo(b.value928);\n            foo(b.value929);\n            foo(b.value930);\n            foo(b.value931);\n            foo(b.value932);\n            foo(b.value933);\n            foo(b.value934);\n            foo(b.value935);\n            foo(b.value936);\n            foo(b.value937);\n            foo(b.value938);\n            foo(b.value939);\n            foo(b.value940);\n            foo(b.value941);\n            foo(b.value942);\n            foo(b.value943);\n            foo(b.value944);\n            foo(b.value945);\n            foo(b.value946);\n            foo(b.value947);\n            foo(b.value948);\n            foo(b.value949);\n            foo(b.value950);\n            foo(b.value951);\n            foo(b.value952);\n            foo(b.value953);\n            foo(b.value954);\n            foo(b.value955);\n            foo(b.value956);\n            foo(b.value957);\n            foo(b.value958);\n            foo(b.value959);\n            foo(b.value960);\n            foo(b.value961);\n            foo(b.value962);\n            foo(b.value963);\n            foo(b.value964);\n            foo(b.value965);\n            foo(b.value966);\n            foo(b.value967);\n            foo(b.value968);\n            foo(b.value969);\n            foo(b.value970);\n            foo(b.value971);\n            foo(b.value972);\n            foo(b.value973);\n            foo(b.value974);\n            foo(b.value975);\n            foo(b.value976);\n            foo(b.value977);\n            foo(b.value978);\n            foo(b.value979);\n            foo(b.value980);\n            foo(b.value981);\n            foo(b.value982);\n            foo(b.value983);\n            foo(b.value984);\n            foo(b.value985);\n            foo(b.value986);\n            foo(b.value987);\n            foo(b.value988);\n            foo(b.value989);\n            foo(b.value990);\n            foo(b.value991);\n            foo(b.value992);\n            foo(b.value993);\n            foo(b.value994);\n            foo(b.value995);\n            foo(b.value996);\n            foo(b.value997);\n            foo(b.value998);\n            foo(b.value999);\n            foo(b.value1000);\n            foo(b.value1001);\n            foo(b.value1002);\n            foo(b.value1003);\n            foo(b.value1004);\n            foo(b.value1005);\n            foo(b.value1006);\n            foo(b.value1007);\n            foo(b.value1008);\n            foo(b.value1009);\n            foo(b.value1010);\n            foo(b.value1011);\n            foo(b.value1012);\n            foo(b.value1013);\n            foo(b.value1014);\n            foo(b.value1015);\n            foo(b.value1016);\n            foo(b.value1017);\n            foo(b.value1018);\n            foo(b.value1019);\n            foo(b.value1020);\n            foo(b.value1021);\n            foo(b.value1022);\n            foo(b.value1023);\n            foo(b.value1024);\n            foo(b.value1025);\n            foo(b.value1026);\n            foo(b.value1027);\n            foo(b.value1028);\n            foo(b.value1029);\n            foo(b.value1030);\n            foo(b.value1031);\n            foo(b.value1032);\n            foo(b.value1033);\n            foo(b.value1034);\n            foo(b.value1035);\n            foo(b.value1036);\n            foo(b.value1037);\n            foo(b.value1038);\n            foo(b.value1039);\n            foo(b.value1040);\n            foo(b.value1041);\n            foo(b.value1042);\n            foo(b.value1043);\n            foo(b.value1044);\n            foo(b.value1045);\n            foo(b.value1046);\n            foo(b.value1047);\n            foo(b.value1048);\n            foo(b.value1049);\n            foo(b.value1050);\n            foo(b.value1051);\n            foo(b.value1052);\n            foo(b.value1053);\n            foo(b.value1054);\n            foo(b.value1055);\n            foo(b.value1056);\n            foo(b.value1057);\n            foo(b.value1058);\n            foo(b.value1059);\n            foo(b.value1060);\n            foo(b.value1061);\n            foo(b.value1062);\n            foo(b.value1063);\n            foo(b.value1064);\n            foo(b.value1065);\n            foo(b.value1066);\n            foo(b.value1067);\n            foo(b.value1068);\n            foo(b.value1069);\n            foo(b.value1070);\n            foo(b.value1071);\n            foo(b.value1072);\n            foo(b.value1073);\n            foo(b.value1074);\n            foo(b.value1075);\n            foo(b.value1076);\n            foo(b.value1077);\n            foo(b.value1078);\n            foo(b.value1079);\n            foo(b.value1080);\n            foo(b.value1081);\n            foo(b.value1082);\n            foo(b.value1083);\n            foo(b.value1084);\n            foo(b.value1085);\n            foo(b.value1086);\n            foo(b.value1087);\n            foo(b.value1088);\n            foo(b.value1089);\n            foo(b.value1090);\n            foo(b.value1091);\n            foo(b.value1092);\n            foo(b.value1093);\n            foo(b.value1094);\n            foo(b.value1095);\n            foo(b.value1096);\n            foo(b.value1097);\n            foo(b.value1098);\n            foo(b.value1099);\n            foo(b.value1100);\n            foo(b.value1101);\n            foo(b.value1102);\n            foo(b.value1103);\n            foo(b.value1104);\n            foo(b.value1105);\n            foo(b.value1106);\n            foo(b.value1107);\n            foo(b.value1108);\n            foo(b.value1109);\n            foo(b.value1110);\n            foo(b.value1111);\n            foo(b.value1112);\n            foo(b.value1113);\n            foo(b.value1114);\n            foo(b.value1115);\n            foo(b.value1116);\n            foo(b.value1117);\n            foo(b.value1118);\n            foo(b.value1119);\n            foo(b.value1120);\n            foo(b.value1121);\n            foo(b.value1122);\n            foo(b.value1123);\n            foo(b.value1124);\n            foo(b.value1125);\n            foo(b.value1126);\n            foo(b.value1127);\n            foo(b.value1128);\n            foo(b.value1129);\n            foo(b.value1130);\n            foo(b.value1131);\n            foo(b.value1132);\n            foo(b.value1133);\n            foo(b.value1134);\n            foo(b.value1135);\n            foo(b.value1136);\n            foo(b.value1137);\n            foo(b.value1138);\n            foo(b.value1139);\n            foo(b.value1140);\n            foo(b.value1141);\n            foo(b.value1142);\n            foo(b.value1143);\n            foo(b.value1144);\n            foo(b.value1145);\n            foo(b.value1146);\n            foo(b.value1147);\n            foo(b.value1148);\n            foo(b.value1149);\n            foo(b.value1150);\n            foo(b.value1151);\n            foo(b.value1152);\n            foo(b.value1153);\n            foo(b.value1154);\n            foo(b.value1155);\n            foo(b.value1156);\n            foo(b.value1157);\n            foo(b.value1158);\n            foo(b.value1159);\n            foo(b.value1160);\n            foo(b.value1161);\n            foo(b.value1162);\n            foo(b.value1163);\n            foo(b.value1164);\n            foo(b.value1165);\n            foo(b.value1166);\n            foo(b.value1167);\n            foo(b.value1168);\n            foo(b.value1169);\n            foo(b.value1170);\n            foo(b.value1171);\n            foo(b.value1172);\n            foo(b.value1173);\n            foo(b.value1174);\n            foo(b.value1175);\n            foo(b.value1176);\n            foo(b.value1177);\n            foo(b.value1178);\n            foo(b.value1179);\n            foo(b.value1180);\n            foo(b.value1181);\n            foo(b.value1182);\n            foo(b.value1183);\n            foo(b.value1184);\n            foo(b.value1185);\n            foo(b.value1186);\n            foo(b.value1187);\n            foo(b.value1188);\n            foo(b.value1189);\n            foo(b.value1190);\n            foo(b.value1191);\n            foo(b.value1192);\n            foo(b.value1193);\n            foo(b.value1194);\n            foo(b.value1195);\n            foo(b.value1196);\n            foo(b.value1197);\n            foo(b.value1198);\n            foo(b.value1199);\n            foo(b.value1200);\n            foo(b.value1201);\n            foo(b.value1202);\n            foo(b.value1203);\n            foo(b.value1204);\n            foo(b.value1205);\n            foo(b.value1206);\n            foo(b.value1207);\n            foo(b.value1208);\n            foo(b.value1209);\n            foo(b.value1210);\n            foo(b.value1211);\n            foo(b.value1212);\n            foo(b.value1213);\n            foo(b.value1214);\n            foo(b.value1215);\n            foo(b.value1216);\n            foo(b.value1217);\n            foo(b.value1218);\n            foo(b.value1219);\n            foo(b.value1220);\n            foo(b.value1221);\n            foo(b.value1222);\n            foo(b.value1223);\n            foo(b.value1224);\n            foo(b.value1225);\n            foo(b.value1226);\n            foo(b.value1227);\n            foo(b.value1228);\n            foo(b.value1229);\n            foo(b.value1230);\n            foo(b.value1231);\n            foo(b.value1232);\n            foo(b.value1233);\n            foo(b.value1234);\n            foo(b.value1235);\n            foo(b.value1236);\n            foo(b.value1237);\n            foo(b.value1238);\n            foo(b.value1239);\n            foo(b.value1240);\n            foo(b.value1241);\n            foo(b.value1242);\n            foo(b.value1243);\n            foo(b.value1244);\n            foo(b.value1245);\n            foo(b.value1246);\n            foo(b.value1247);\n            foo(b.value1248);\n            foo(b.value1249);\n            foo(b.value1250);\n            foo(b.value1251);\n            foo(b.value1252);\n            foo(b.value1253);\n            foo(b.value1254);\n            foo(b.value1255);\n            foo(b.value1256);\n            foo(b.value1257);\n            foo(b.value1258);\n            foo(b.value1259);\n            foo(b.value1260);\n            foo(b.value1261);\n            foo(b.value1262);\n            foo(b.value1263);\n            foo(b.value1264);\n            foo(b.value1265);\n            foo(b.value1266);\n            foo(b.value1267);\n            foo(b.value1268);\n            foo(b.value1269);\n            foo(b.value1270);\n            foo(b.value1271);\n            foo(b.value1272);\n            foo(b.value1273);\n            foo(b.value1274);\n            foo(b.value1275);\n            foo(b.value1276);\n            foo(b.value1277);\n            foo(b.value1278);\n            foo(b.value1279);\n            foo(b.value1280);\n            foo(b.value1281);\n            foo(b.value1282);\n            foo(b.value1283);\n            foo(b.value1284);\n            foo(b.value1285);\n            foo(b.value1286);\n            foo(b.value1287);\n            foo(b.value1288);\n            foo(b.value1289);\n            foo(b.value1290);\n            foo(b.value1291);\n            foo(b.value1292);\n            foo(b.value1293);\n            foo(b.value1294);\n            foo(b.value1295);\n            foo(b.value1296);\n            foo(b.value1297);\n            foo(b.value1298);\n            foo(b.value1299);\n            foo(b.value1300);\n            foo(b.value1301);\n            foo(b.value1302);\n            foo(b.value1303);\n            foo(b.value1304);\n            foo(b.value1305);\n            foo(b.value1306);\n            foo(b.value1307);\n            foo(b.value1308);\n            foo(b.value1309);\n            foo(b.value1310);\n            foo(b.value1311);\n            foo(b.value1312);\n            foo(b.value1313);\n            foo(b.value1314);\n            foo(b.value1315);\n            foo(b.value1316);\n            foo(b.value1317);\n            foo(b.value1318);\n            foo(b.value1319);\n            foo(b.value1320);\n            foo(b.value1321);\n            foo(b.value1322);\n            foo(b.value1323);\n            foo(b.value1324);\n            foo(b.value1325);\n            foo(b.value1326);\n            foo(b.value1327);\n            foo(b.value1328);\n            foo(b.value1329);\n            foo(b.value1330);\n            foo(b.value1331);\n            foo(b.value1332);\n            foo(b.value1333);\n            foo(b.value1334);\n            foo(b.value1335);\n            foo(b.value1336);\n            foo(b.value1337);\n            foo(b.value1338);\n            foo(b.value1339);\n            foo(b.value1340);\n            foo(b.value1341);\n            foo(b.value1342);\n            foo(b.value1343);\n            foo(b.value1344);\n            foo(b.value1345);\n            foo(b.value1346);\n            foo(b.value1347);\n            foo(b.value1348);\n            foo(b.value1349);\n            foo(b.value1350);\n            foo(b.value1351);\n            foo(b.value1352);\n            foo(b.value1353);\n            foo(b.value1354);\n            foo(b.value1355);\n            foo(b.value1356);\n            foo(b.value1357);\n            foo(b.value1358);\n            foo(b.value1359);\n            foo(b.value1360);\n            foo(b.value1361);\n            foo(b.value1362);\n            foo(b.value1363);\n            foo(b.value1364);\n            foo(b.value1365);\n            foo(b.value1366);\n            foo(b.value1367);\n            foo(b.value1368);\n            foo(b.value1369);\n            foo(b.value1370);\n            foo(b.value1371);\n            foo(b.value1372);\n            foo(b.value1373);\n            foo(b.value1374);\n            foo(b.value1375);\n            foo(b.value1376);\n            foo(b.value1377);\n            foo(b.value1378);\n            foo(b.value1379);\n            foo(b.value1380);\n            foo(b.value1381);\n            foo(b.value1382);\n            foo(b.value1383);\n            foo(b.value1384);\n            foo(b.value1385);\n            foo(b.value1386);\n            foo(b.value1387);\n            foo(b.value1388);\n            foo(b.value1389);\n            foo(b.value1390);\n            foo(b.value1391);\n            foo(b.value1392);\n            foo(b.value1393);\n            foo(b.value1394);\n            foo(b.value1395);\n            foo(b.value1396);\n            foo(b.value1397);\n            foo(b.value1398);\n            foo(b.value1399);\n            foo(b.value1400);\n            foo(b.value1401);\n            foo(b.value1402);\n            foo(b.value1403);\n            foo(b.value1404);\n            foo(b.value1405);\n            foo(b.value1406);\n            foo(b.value1407);\n            foo(b.value1408);\n            foo(b.value1409);\n            foo(b.value1410);\n            foo(b.value1411);\n            foo(b.value1412);\n            foo(b.value1413);\n            foo(b.value1414);\n            foo(b.value1415);\n            foo(b.value1416);\n            foo(b.value1417);\n            foo(b.value1418);\n            foo(b.value1419);\n            foo(b.value1420);\n            foo(b.value1421);\n            foo(b.value1422);\n            foo(b.value1423);\n            foo(b.value1424);\n            foo(b.value1425);\n            foo(b.value1426);\n            foo(b.value1427);\n            foo(b.value1428);\n            foo(b.value1429);\n            foo(b.value1430);\n            foo(b.value1431);\n            foo(b.value1432);\n            foo(b.value1433);\n            foo(b.value1434);\n            foo(b.value1435);\n            foo(b.value1436);\n            foo(b.value1437);\n            foo(b.value1438);\n            foo(b.value1439);\n            foo(b.value1440);\n            foo(b.value1441);\n            foo(b.value1442);\n            foo(b.value1443);\n            foo(b.value1444);\n            foo(b.value1445);\n            foo(b.value1446);\n            foo(b.value1447);\n            foo(b.value1448);\n            foo(b.value1449);\n            foo(b.value1450);\n            foo(b.value1451);\n            foo(b.value1452);\n            foo(b.value1453);\n            foo(b.value1454);\n            foo(b.value1455);\n            foo(b.value1456);\n            foo(b.value1457);\n            foo(b.value1458);\n            foo(b.value1459);\n            foo(b.value1460);\n            foo(b.value1461);\n            foo(b.value1462);\n            foo(b.value1463);\n            foo(b.value1464);\n            foo(b.value1465);\n            foo(b.value1466);\n            foo(b.value1467);\n            foo(b.value1468);\n            foo(b.value1469);\n            foo(b.value1470);\n            foo(b.value1471);\n            foo(b.value1472);\n            foo(b.value1473);\n            foo(b.value1474);\n            foo(b.value1475);\n            foo(b.value1476);\n            foo(b.value1477);\n            foo(b.value1478);\n            foo(b.value1479);\n            foo(b.value1480);\n            foo(b.value1481);\n            foo(b.value1482);\n            foo(b.value1483);\n            foo(b.value1484);\n            foo(b.value1485);\n            foo(b.value1486);\n            foo(b.value1487);\n            foo(b.value1488);\n            foo(b.value1489);\n            foo(b.value1490);\n            foo(b.value1491);\n            foo(b.value1492);\n            foo(b.value1493);\n            foo(b.value1494);\n            foo(b.value1495);\n            foo(b.value1496);\n            foo(b.value1497);\n            foo(b.value1498);\n            foo(b.value1499);\n            foo(b.value1500);\n            foo(b.value1501);\n            foo(b.value1502);\n            foo(b.value1503);\n            foo(b.value1504);\n            foo(b.value1505);\n            foo(b.value1506);\n            foo(b.value1507);\n            foo(b.value1508);\n            foo(b.value1509);\n            foo(b.value1510);\n            foo(b.value1511);\n            foo(b.value1512);\n            foo(b.value1513);\n            foo(b.value1514);\n            foo(b.value1515);\n            foo(b.value1516);\n            foo(b.value1517);\n            foo(b.value1518);\n            foo(b.value1519);\n            foo(b.value1520);\n            foo(b.value1521);\n            foo(b.value1522);\n            foo(b.value1523);\n            foo(b.value1524);\n            foo(b.value1525);\n            foo(b.value1526);\n            foo(b.value1527);\n            foo(b.value1528);\n            foo(b.value1529);\n            foo(b.value1530);\n            foo(b.value1531);\n            foo(b.value1532);\n            foo(b.value1533);\n            foo(b.value1534);\n            foo(b.value1535);\n            foo(b.value1536);\n            foo(b.value1537);\n            foo(b.value1538);\n            foo(b.value1539);\n            foo(b.value1540);\n            foo(b.value1541);\n            foo(b.value1542);\n            foo(b.value1543);\n            foo(b.value1544);\n            foo(b.value1545);\n            foo(b.value1546);\n            foo(b.value1547);\n            foo(b.value1548);\n            foo(b.value1549);\n            foo(b.value1550);\n            foo(b.value1551);\n            foo(b.value1552);\n            foo(b.value1553);\n            foo(b.value1554);\n            foo(b.value1555);\n            foo(b.value1556);\n            foo(b.value1557);\n            foo(b.value1558);\n            foo(b.value1559);\n            foo(b.value1560);\n            foo(b.value1561);\n            foo(b.value1562);\n            foo(b.value1563);\n            foo(b.value1564);\n            foo(b.value1565);\n            foo(b.value1566);\n            foo(b.value1567);\n            foo(b.value1568);\n            foo(b.value1569);\n            foo(b.value1570);\n            foo(b.value1571);\n            foo(b.value1572);\n            foo(b.value1573);\n            foo(b.value1574);\n            foo(b.value1575);\n            foo(b.value1576);\n            foo(b.value1577);\n            foo(b.value1578);\n            foo(b.value1579);\n            foo(b.value1580);\n            foo(b.value1581);\n            foo(b.value1582);\n            foo(b.value1583);\n            foo(b.value1584);\n            foo(b.value1585);\n            foo(b.value1586);\n            foo(b.value1587);\n            foo(b.value1588);\n            foo(b.value1589);\n            foo(b.value1590);\n            foo(b.value1591);\n            foo(b.value1592);\n            foo(b.value1593);\n            foo(b.value1594);\n            foo(b.value1595);\n            foo(b.value1596);\n            foo(b.value1597);\n            foo(b.value1598);\n            foo(b.value1599);\n            foo(b.value1600);\n            foo(b.value1601);\n            foo(b.value1602);\n            foo(b.value1603);\n            foo(b.value1604);\n            foo(b.value1605);\n            foo(b.value1606);\n            foo(b.value1607);\n            foo(b.value1608);\n            foo(b.value1609);\n            foo(b.value1610);\n            foo(b.value1611);\n            foo(b.value1612);\n            foo(b.value1613);\n            foo(b.value1614);\n            foo(b.value1615);\n            foo(b.value1616);\n            foo(b.value1617);\n            foo(b.value1618);\n            foo(b.value1619);\n            foo(b.value1620);\n            foo(b.value1621);\n            foo(b.value1622);\n            foo(b.value1623);\n            foo(b.value1624);\n            foo(b.value1625);\n            foo(b.value1626);\n            foo(b.value1627);\n            foo(b.value1628);\n            foo(b.value1629);\n            foo(b.value1630);\n            foo(b.value1631);\n            foo(b.value1632);\n            foo(b.value1633);\n            foo(b.value1634);\n            foo(b.value1635);\n            foo(b.value1636);\n            foo(b.value1637);\n            foo(b.value1638);\n            foo(b.value1639);\n            foo(b.value1640);\n            foo(b.value1641);\n            foo(b.value1642);\n            foo(b.value1643);\n            foo(b.value1644);\n            foo(b.value1645);\n            foo(b.value1646);\n            foo(b.value1647);\n            foo(b.value1648);\n            foo(b.value1649);\n            foo(b.value1650);\n            foo(b.value1651);\n            foo(b.value1652);\n            foo(b.value1653);\n            foo(b.value1654);\n            foo(b.value1655);\n            foo(b.value1656);\n            foo(b.value1657);\n            foo(b.value1658);\n            foo(b.value1659);\n            foo(b.value1660);\n            foo(b.value1661);\n            foo(b.value1662);\n            foo(b.value1663);\n            foo(b.value1664);\n            foo(b.value1665);\n            foo(b.value1666);\n            foo(b.value1667);\n            foo(b.value1668);\n            foo(b.value1669);\n            foo(b.value1670);\n            foo(b.value1671);\n            foo(b.value1672);\n            foo(b.value1673);\n            foo(b.value1674);\n            foo(b.value1675);\n            foo(b.value1676);\n            foo(b.value1677);\n            foo(b.value1678);\n            foo(b.value1679);\n            foo(b.value1680);\n            foo(b.value1681);\n            foo(b.value1682);\n            foo(b.value1683);\n            foo(b.value1684);\n            foo(b.value1685);\n            foo(b.value1686);\n            foo(b.value1687);\n            foo(b.value1688);\n            foo(b.value1689);\n            foo(b.value1690);\n            foo(b.value1691);\n            foo(b.value1692);\n            foo(b.value1693);\n            foo(b.value1694);\n            foo(b.value1695);\n            foo(b.value1696);\n            foo(b.value1697);\n            foo(b.value1698);\n            foo(b.value1699);\n            foo(b.value1700);\n            foo(b.value1701);\n            foo(b.value1702);\n            foo(b.value1703);\n            foo(b.value1704);\n            foo(b.value1705);\n            foo(b.value1706);\n            foo(b.value1707);\n            foo(b.value1708);\n            foo(b.value1709);\n            foo(b.value1710);\n            foo(b.value1711);\n            foo(b.value1712);\n            foo(b.value1713);\n            foo(b.value1714);\n            foo(b.value1715);\n            foo(b.value1716);\n            foo(b.value1717);\n            foo(b.value1718);\n            foo(b.value1719);\n            foo(b.value1720);\n            foo(b.value1721);\n            foo(b.value1722);\n            foo(b.value1723);\n            foo(b.value1724);\n            foo(b.value1725);\n            foo(b.value1726);\n            foo(b.value1727);\n            foo(b.value1728);\n            foo(b.value1729);\n            foo(b.value1730);\n            foo(b.value1731);\n            foo(b.value1732);\n            foo(b.value1733);\n            foo(b.value1734);\n            foo(b.value1735);\n            foo(b.value1736);\n            foo(b.value1737);\n            foo(b.value1738);\n            foo(b.value1739);\n            foo(b.value1740);\n            foo(b.value1741);\n            foo(b.value1742);\n            foo(b.value1743);\n            foo(b.value1744);\n            foo(b.value1745);\n            foo(b.value1746);\n            foo(b.value1747);\n            foo(b.value1748);\n            foo(b.value1749);\n            foo(b.value1750);\n            foo(b.value1751);\n            foo(b.value1752);\n            foo(b.value1753);\n            foo(b.value1754);\n            foo(b.value1755);\n            foo(b.value1756);\n            foo(b.value1757);\n            foo(b.value1758);\n            foo(b.value1759);\n            foo(b.value1760);\n            foo(b.value1761);\n            foo(b.value1762);\n            foo(b.value1763);\n            foo(b.value1764);\n            foo(b.value1765);\n            foo(b.value1766);\n            foo(b.value1767);\n            foo(b.value1768);\n            foo(b.value1769);\n            foo(b.value1770);\n            foo(b.value1771);\n            foo(b.value1772);\n            foo(b.value1773);\n            foo(b.value1774);\n            foo(b.value1775);\n            foo(b.value1776);\n            foo(b.value1777);\n            foo(b.value1778);\n            foo(b.value1779);\n            foo(b.value1780);\n            foo(b.value1781);\n            foo(b.value1782);\n            foo(b.value1783);\n            foo(b.value1784);\n            foo(b.value1785);\n            foo(b.value1786);\n            foo(b.value1787);\n            foo(b.value1788);\n            foo(b.value1789);\n            foo(b.value1790);\n            foo(b.value1791);\n            foo(b.value1792);\n            foo(b.value1793);\n            foo(b.value1794);\n            foo(b.value1795);\n            foo(b.value1796);\n            foo(b.value1797);\n            foo(b.value1798);\n            foo(b.value1799);\n            foo(b.value1800);\n            foo(b.value1801);\n            foo(b.value1802);\n            foo(b.value1803);\n            foo(b.value1804);\n            foo(b.value1805);\n            foo(b.value1806);\n            foo(b.value1807);\n            foo(b.value1808);\n            foo(b.value1809);\n            foo(b.value1810);\n            foo(b.value1811);\n            foo(b.value1812);\n            foo(b.value1813);\n            foo(b.value1814);\n            foo(b.value1815);\n            foo(b.value1816);\n            foo(b.value1817);\n            foo(b.value1818);\n            foo(b.value1819);\n            foo(b.value1820);\n            foo(b.value1821);\n            foo(b.value1822);\n            foo(b.value1823);\n            foo(b.value1824);\n            foo(b.value1825);\n            foo(b.value1826);\n            foo(b.value1827);\n            foo(b.value1828);\n            foo(b.value1829);\n            foo(b.value1830);\n            foo(b.value1831);\n            foo(b.value1832);\n            foo(b.value1833);\n            foo(b.value1834);\n            foo(b.value1835);\n            foo(b.value1836);\n            foo(b.value1837);\n            foo(b.value1838);\n            foo(b.value1839);\n            foo(b.value1840);\n            foo(b.value1841);\n            foo(b.value1842);\n            foo(b.value1843);\n            foo(b.value1844);\n            foo(b.value1845);\n            foo(b.value1846);\n            foo(b.value1847);\n            foo(b.value1848);\n            foo(b.value1849);\n            foo(b.value1850);\n            foo(b.value1851);\n            foo(b.value1852);\n            foo(b.value1853);\n            foo(b.value1854);\n            foo(b.value1855);\n            foo(b.value1856);\n            foo(b.value1857);\n            foo(b.value1858);\n            foo(b.value1859);\n            foo(b.value1860);\n            foo(b.value1861);\n            foo(b.value1862);\n            foo(b.value1863);\n            foo(b.value1864);\n            foo(b.value1865);\n            foo(b.value1866);\n            foo(b.value1867);\n            foo(b.value1868);\n            foo(b.value1869);\n            foo(b.value1870);\n            foo(b.value1871);\n            foo(b.value1872);\n            foo(b.value1873);\n            foo(b.value1874);\n            foo(b.value1875);\n            foo(b.value1876);\n            foo(b.value1877);\n            foo(b.value1878);\n            foo(b.value1879);\n            foo(b.value1880);\n            foo(b.value1881);\n            foo(b.value1882);\n            foo(b.value1883);\n            foo(b.value1884);\n            foo(b.value1885);\n            foo(b.value1886);\n            foo(b.value1887);\n            foo(b.value1888);\n            foo(b.value1889);\n            foo(b.value1890);\n            foo(b.value1891);\n            foo(b.value1892);\n            foo(b.value1893);\n            foo(b.value1894);\n            foo(b.value1895);\n            foo(b.value1896);\n            foo(b.value1897);\n            foo(b.value1898);\n            foo(b.value1899);\n            foo(b.value1900);\n            foo(b.value1901);\n            foo(b.value1902);\n            foo(b.value1903);\n            foo(b.value1904);\n            foo(b.value1905);\n            foo(b.value1906);\n            foo(b.value1907);\n            foo(b.value1908);\n            foo(b.value1909);\n            foo(b.value1910);\n            foo(b.value1911);\n            foo(b.value1912);\n            foo(b.value1913);\n            foo(b.value1914);\n            foo(b.value1915);\n            foo(b.value1916);\n            foo(b.value1917);\n            foo(b.value1918);\n            foo(b.value1919);\n            foo(b.value1920);\n            foo(b.value1921);\n            foo(b.value1922);\n            foo(b.value1923);\n            foo(b.value1924);\n            foo(b.value1925);\n            foo(b.value1926);\n            foo(b.value1927);\n            foo(b.value1928);\n            foo(b.value1929);\n            foo(b.value1930);\n            foo(b.value1931);\n            foo(b.value1932);\n            foo(b.value1933);\n            foo(b.value1934);\n            foo(b.value1935);\n            foo(b.value1936);\n            foo(b.value1937);\n            foo(b.value1938);\n            foo(b.value1939);\n            foo(b.value1940);\n            foo(b.value1941);\n            foo(b.value1942);\n            foo(b.value1943);\n            foo(b.value1944);\n            foo(b.value1945);\n            foo(b.value1946);\n            foo(b.value1947);\n            foo(b.value1948);\n            foo(b.value1949);\n            foo(b.value1950);\n            foo(b.value1951);\n            foo(b.value1952);\n            foo(b.value1953);\n            foo(b.value1954);\n            foo(b.value1955);\n            foo(b.value1956);\n            foo(b.value1957);\n            foo(b.value1958);\n            foo(b.value1959);\n            foo(b.value1960);\n            foo(b.value1961);\n            foo(b.value1962);\n            foo(b.value1963);\n            foo(b.value1964);\n            foo(b.value1965);\n            foo(b.value1966);\n            foo(b.value1967);\n            foo(b.value1968);\n            foo(b.value1969);\n            foo(b.value1970);\n            foo(b.value1971);\n            foo(b.value1972);\n            foo(b.value1973);\n            foo(b.value1974);\n            foo(b.value1975);\n            foo(b.value1976);\n            foo(b.value1977);\n            foo(b.value1978);\n            foo(b.value1979);\n            foo(b.value1980);\n            foo(b.value1981);\n            foo(b.value1982);\n            foo(b.value1983);\n            foo(b.value1984);\n            foo(b.value1985);\n            foo(b.value1986);\n            foo(b.value1987);\n            foo(b.value1988);\n            foo(b.value1989);\n            foo(b.value1990);\n            foo(b.value1991);\n            foo(b.value1992);\n            foo(b.value1993);\n            foo(b.value1994);\n            foo(b.value1995);\n            foo(b.value1996);\n            foo(b.value1997);\n            foo(b.value1998);\n            foo(b.value1999);\n            foo(b.value2000);\n            foo(b.value2001);\n            foo(b.value2002);\n            foo(b.value2003);\n            foo(b.value2004);\n            foo(b.value2005);\n            foo(b.value2006);\n            foo(b.value2007);\n            foo(b.value2008);\n            foo(b.value2009);\n            foo(b.value2010);\n            foo(b.value2011);\n            foo(b.value2012);\n            foo(b.value2013);\n            foo(b.value2014);\n            foo(b.value2015);\n            foo(b.value2016);\n            foo(b.value2017);\n            foo(b.value2018);\n            foo(b.value2019);\n            foo(b.value2020);\n            foo(b.value2021);\n            foo(b.value2022);\n            foo(b.value2023);\n            foo(b.value2024);\n            foo(b.value2025);\n            foo(b.value2026);\n            foo(b.value2027);\n            foo(b.value2028);\n            foo(b.value2029);\n            foo(b.value2030);\n            foo(b.value2031);\n            foo(b.value2032);\n            foo(b.value2033);\n            foo(b.value2034);\n            foo(b.value2035);\n            foo(b.value2036);\n            foo(b.value2037);\n            foo(b.value2038);\n            foo(b.value2039);\n            foo(b.value2040);\n            foo(b.value2041);\n            foo(b.value2042);\n            foo(b.value2043);\n            foo(b.value2044);\n            foo(b.value2045);\n            foo(b.value2046);\n            foo(b.value2047);\n            foo(b.value2048);\n            foo(b.value2049);\n            foo(b.value2050);\n            foo(b.value2051);\n            foo(b.value2052);\n            foo(b.value2053);\n            foo(b.value2054);\n            foo(b.value2055);\n            foo(b.value2056);\n            foo(b.value2057);\n            foo(b.value2058);\n            foo(b.value2059);\n            foo(b.value2060);\n            foo(b.value2061);\n            foo(b.value2062);\n            foo(b.value2063);\n            foo(b.value2064);\n            foo(b.value2065);\n            foo(b.value2066);\n            foo(b.value2067);\n            foo(b.value2068);\n            foo(b.value2069);\n            foo(b.value2070);\n            foo(b.value2071);\n            foo(b.value2072);\n            foo(b.value2073);\n            foo(b.value2074);\n            foo(b.value2075);\n            foo(b.value2076);\n            foo(b.value2077);\n            foo(b.value2078);\n            foo(b.value2079);\n            foo(b.value2080);\n            foo(b.value2081);\n            foo(b.value2082);\n            foo(b.value2083);\n            foo(b.value2084);\n            foo(b.value2085);\n            foo(b.value2086);\n            foo(b.value2087);\n            foo(b.value2088);\n            foo(b.value2089);\n            foo(b.value2090);\n            foo(b.value2091);\n            foo(b.value2092);\n            foo(b.value2093);\n            foo(b.value2094);\n            foo(b.value2095);\n            foo(b.value2096);\n            foo(b.value2097);\n            foo(b.value2098);\n            foo(b.value2099);\n            foo(b.value2100);\n            foo(b.value2101);\n            foo(b.value2102);\n            foo(b.value2103);\n            foo(b.value2104);\n            foo(b.value2105);\n            foo(b.value2106);\n            foo(b.value2107);\n            foo(b.value2108);\n            foo(b.value2109);\n            foo(b.value2110);\n            foo(b.value2111);\n            foo(b.value2112);\n            foo(b.value2113);\n            foo(b.value2114);\n            foo(b.value2115);\n            foo(b.value2116);\n            foo(b.value2117);\n            foo(b.value2118);\n            foo(b.value2119);\n            foo(b.value2120);\n            foo(b.value2121);\n            foo(b.value2122);\n            foo(b.value2123);\n            foo(b.value2124);\n            foo(b.value2125);\n            foo(b.value2126);\n            foo(b.value2127);\n            foo(b.value2128);\n            foo(b.value2129);\n            foo(b.value2130);\n            foo(b.value2131);\n            foo(b.value2132);\n            foo(b.value2133);\n            foo(b.value2134);\n            foo(b.value2135);\n            foo(b.value2136);\n            foo(b.value2137);\n            foo(b.value2138);\n            foo(b.value2139);\n            foo(b.value2140);\n            foo(b.value2141);\n            foo(b.value2142);\n            foo(b.value2143);\n            foo(b.value2144);\n            foo(b.value2145);\n            foo(b.value2146);\n            foo(b.value2147);\n            foo(b.value2148);\n            foo(b.value2149);\n            foo(b.value2150);\n            foo(b.value2151);\n            foo(b.value2152);\n            foo(b.value2153);\n            foo(b.value2154);\n            foo(b.value2155);\n            foo(b.value2156);\n            foo(b.value2157);\n            foo(b.value2158);\n            foo(b.value2159);\n            foo(b.value2160);\n            foo(b.value2161);\n            foo(b.value2162);\n            foo(b.value2163);\n            foo(b.value2164);\n            foo(b.value2165);\n            foo(b.value2166);\n            foo(b.value2167);\n            foo(b.value2168);\n            foo(b.value2169);\n            foo(b.value2170);\n            foo(b.value2171);\n            foo(b.value2172);\n            foo(b.value2173);\n            foo(b.value2174);\n            foo(b.value2175);\n            foo(b.value2176);\n            foo(b.value2177);\n            foo(b.value2178);\n            foo(b.value2179);\n            foo(b.value2180);\n            foo(b.value2181);\n            foo(b.value2182);\n            foo(b.value2183);\n            foo(b.value2184);\n            foo(b.value2185);\n            foo(b.value2186);\n            foo(b.value2187);\n            foo(b.value2188);\n            foo(b.value2189);\n            foo(b.value2190);\n            foo(b.value2191);\n            foo(b.value2192);\n            foo(b.value2193);\n            foo(b.value2194);\n            foo(b.value2195);\n            foo(b.value2196);\n            foo(b.value2197);\n            foo(b.value2198);\n            foo(b.value2199);\n            foo(b.value2200);\n            foo(b.value2201);\n            foo(b.value2202);\n            foo(b.value2203);\n            foo(b.value2204);\n            foo(b.value2205);\n            foo(b.value2206);\n            foo(b.value2207);\n            foo(b.value2208);\n            foo(b.value2209);\n            foo(b.value2210);\n            foo(b.value2211);\n            foo(b.value2212);\n            foo(b.value2213);\n            foo(b.value2214);\n            foo(b.value2215);\n            foo(b.value2216);\n            foo(b.value2217);\n            foo(b.value2218);\n            foo(b.value2219);\n            foo(b.value2220);\n            foo(b.value2221);\n            foo(b.value2222);\n            foo(b.value2223);\n            foo(b.value2224);\n            foo(b.value2225);\n            foo(b.value2226);\n            foo(b.value2227);\n            foo(b.value2228);\n            foo(b.value2229);\n            foo(b.value2230);\n            foo(b.value2231);\n            foo(b.value2232);\n            foo(b.value2233);\n            foo(b.value2234);\n            foo(b.value2235);\n            foo(b.value2236);\n            foo(b.value2237);\n            foo(b.value2238);\n            foo(b.value2239);\n            foo(b.value2240);\n            foo(b.value2241);\n            foo(b.value2242);\n            foo(b.value2243);\n            foo(b.value2244);\n            foo(b.value2245);\n            foo(b.value2246);\n            foo(b.value2247);\n            foo(b.value2248);\n            foo(b.value2249);\n            foo(b.value2250);\n            foo(b.value2251);\n            foo(b.value2252);\n            foo(b.value2253);\n            foo(b.value2254);\n            foo(b.value2255);\n            foo(b.value2256);\n            foo(b.value2257);\n            foo(b.value2258);\n            foo(b.value2259);\n            foo(b.value2260);\n            foo(b.value2261);\n            foo(b.value2262);\n            foo(b.value2263);\n            foo(b.value2264);\n            foo(b.value2265);\n            foo(b.value2266);\n            foo(b.value2267);\n            foo(b.value2268);\n            foo(b.value2269);\n            foo(b.value2270);\n            foo(b.value2271);\n            foo(b.value2272);\n            foo(b.value2273);\n            foo(b.value2274);\n            foo(b.value2275);\n            foo(b.value2276);\n            foo(b.value2277);\n            foo(b.value2278);\n            foo(b.value2279);\n            foo(b.value2280);\n            foo(b.value2281);\n            foo(b.value2282);\n            foo(b.value2283);\n            foo(b.value2284);\n            foo(b.value2285);\n            foo(b.value2286);\n            foo(b.value2287);\n            foo(b.value2288);\n            foo(b.value2289);\n            foo(b.value2290);\n            foo(b.value2291);\n            foo(b.value2292);\n            foo(b.value2293);\n            foo(b.value2294);\n            foo(b.value2295);\n            foo(b.value2296);\n            foo(b.value2297);\n            foo(b.value2298);\n            foo(b.value2299);\n            foo(b.value2300);\n            foo(b.value2301);\n            foo(b.value2302);\n            foo(b.value2303);\n            foo(b.value2304);\n            foo(b.value2305);\n            foo(b.value2306);\n            foo(b.value2307);\n            foo(b.value2308);\n            foo(b.value2309);\n            foo(b.value2310);\n            foo(b.value2311);\n            foo(b.value2312);\n            foo(b.value2313);\n            foo(b.value2314);\n            foo(b.value2315);\n            foo(b.value2316);\n            foo(b.value2317);\n            foo(b.value2318);\n            foo(b.value2319);\n            foo(b.value2320);\n            foo(b.value2321);\n            foo(b.value2322);\n            foo(b.value2323);\n            foo(b.value2324);\n            foo(b.value2325);\n            foo(b.value2326);\n            foo(b.value2327);\n            foo(b.value2328);\n            foo(b.value2329);\n            foo(b.value2330);\n            foo(b.value2331);\n            foo(b.value2332);\n            foo(b.value2333);\n            foo(b.value2334);\n            foo(b.value2335);\n            foo(b.value2336);\n            foo(b.value2337);\n            foo(b.value2338);\n            foo(b.value2339);\n            foo(b.value2340);\n            foo(b.value2341);\n            foo(b.value2342);\n            foo(b.value2343);\n            foo(b.value2344);\n            foo(b.value2345);\n            foo(b.value2346);\n            foo(b.value2347);\n            foo(b.value2348);\n            foo(b.value2349);\n            foo(b.value2350);\n            foo(b.value2351);\n            foo(b.value2352);\n            foo(b.value2353);\n            foo(b.value2354);\n            foo(b.value2355);\n            foo(b.value2356);\n            foo(b.value2357);\n            foo(b.value2358);\n            foo(b.value2359);\n            foo(b.value2360);\n            foo(b.value2361);\n            foo(b.value2362);\n            foo(b.value2363);\n            foo(b.value2364);\n            foo(b.value2365);\n            foo(b.value2366);\n            foo(b.value2367);\n            foo(b.value2368);\n            foo(b.value2369);\n            foo(b.value2370);\n            foo(b.value2371);\n            foo(b.value2372);\n            foo(b.value2373);\n            foo(b.value2374);\n            foo(b.value2375);\n            foo(b.value2376);\n            foo(b.value2377);\n            foo(b.value2378);\n            foo(b.value2379);\n            foo(b.value2380);\n            foo(b.value2381);\n            foo(b.value2382);\n            foo(b.value2383);\n            foo(b.value2384);\n            foo(b.value2385);\n            foo(b.value2386);\n            foo(b.value2387);\n            foo(b.value2388);\n            foo(b.value2389);\n            foo(b.value2390);\n            foo(b.value2391);\n            foo(b.value2392);\n            foo(b.value2393);\n            foo(b.value2394);\n            foo(b.value2395);\n            foo(b.value2396);\n            foo(b.value2397);\n            foo(b.value2398);\n            foo(b.value2399);\n            foo(b.value2400);\n            foo(b.value2401);\n            foo(b.value2402);\n            foo(b.value2403);\n            foo(b.value2404);\n            foo(b.value2405);\n            foo(b.value2406);\n            foo(b.value2407);\n            foo(b.value2408);\n            foo(b.value2409);\n            foo(b.value2410);\n            foo(b.value2411);\n            foo(b.value2412);\n            foo(b.value2413);\n            foo(b.value2414);\n            foo(b.value2415);\n            foo(b.value2416);\n            foo(b.value2417);\n            foo(b.value2418);\n            foo(b.value2419);\n            foo(b.value2420);\n            foo(b.value2421);\n            foo(b.value2422);\n            foo(b.value2423);\n            foo(b.value2424);\n            foo(b.value2425);\n            foo(b.value2426);\n            foo(b.value2427);\n            foo(b.value2428);\n            foo(b.value2429);\n            foo(b.value2430);\n            foo(b.value2431);\n            foo(b.value2432);\n            foo(b.value2433);\n            foo(b.value2434);\n            foo(b.value2435);\n            foo(b.value2436);\n            foo(b.value2437);\n            foo(b.value2438);\n            foo(b.value2439);\n            foo(b.value2440);\n            foo(b.value2441);\n            foo(b.value2442);\n            foo(b.value2443);\n            foo(b.value2444);\n            foo(b.value2445);\n            foo(b.value2446);\n            foo(b.value2447);\n            foo(b.value2448);\n            foo(b.value2449);\n            foo(b.value2450);\n            foo(b.value2451);\n            foo(b.value2452);\n            foo(b.value2453);\n            foo(b.value2454);\n            foo(b.value2455);\n            foo(b.value2456);\n            foo(b.value2457);\n            foo(b.value2458);\n            foo(b.value2459);\n            foo(b.value2460);\n            foo(b.value2461);\n            foo(b.value2462);\n            foo(b.value2463);\n            foo(b.value2464);\n            foo(b.value2465);\n            foo(b.value2466);\n            foo(b.value2467);\n            foo(b.value2468);\n            foo(b.value2469);\n            foo(b.value2470);\n            foo(b.value2471);\n            foo(b.value2472);\n            foo(b.value2473);\n            foo(b.value2474);\n            foo(b.value2475);\n            foo(b.value2476);\n            foo(b.value2477);\n            foo(b.value2478);\n            foo(b.value2479);\n            foo(b.value2480);\n            foo(b.value2481);\n            foo(b.value2482);\n            foo(b.value2483);\n            foo(b.value2484);\n            foo(b.value2485);\n            foo(b.value2486);\n            foo(b.value2487);\n            foo(b.value2488);\n            foo(b.value2489);\n            foo(b.value2490);\n            foo(b.value2491);\n            foo(b.value2492);\n            foo(b.value2493);\n            foo(b.value2494);\n            foo(b.value2495);\n            foo(b.value2496);\n            foo(b.value2497);\n            foo(b.value2498);\n            foo(b.value2499);\n            foo(b.value2500);\n            foo(b.value2501);\n            foo(b.value2502);\n            foo(b.value2503);\n            foo(b.value2504);\n            foo(b.value2505);\n            foo(b.value2506);\n            foo(b.value2507);\n            foo(b.value2508);\n            foo(b.value2509);\n            foo(b.value2510);\n            foo(b.value2511);\n            foo(b.value2512);\n            foo(b.value2513);\n            foo(b.value2514);\n            foo(b.value2515);\n            foo(b.value2516);\n            foo(b.value2517);\n            foo(b.value2518);\n            foo(b.value2519);\n            foo(b.value2520);\n            foo(b.value2521);\n            foo(b.value2522);\n            foo(b.value2523);\n            foo(b.value2524);\n            foo(b.value2525);\n            foo(b.value2526);\n            foo(b.value2527);\n            foo(b.value2528);\n            foo(b.value2529);\n            foo(b.value2530);\n            foo(b.value2531);\n            foo(b.value2532);\n            foo(b.value2533);\n            foo(b.value2534);\n            foo(b.value2535);\n            foo(b.value2536);\n            foo(b.value2537);\n            foo(b.value2538);\n            foo(b.value2539);\n            foo(b.value2540);\n            foo(b.value2541);\n            foo(b.value2542);\n            foo(b.value2543);\n            foo(b.value2544);\n            foo(b.value2545);\n            foo(b.value2546);\n            foo(b.value2547);\n            foo(b.value2548);\n            foo(b.value2549);\n            foo(b.value2550);\n            foo(b.value2551);\n            foo(b.value2552);\n            foo(b.value2553);\n            foo(b.value2554);\n            foo(b.value2555);\n            foo(b.value2556);\n            foo(b.value2557);\n            foo(b.value2558);\n            foo(b.value2559);\n            foo(b.value2560);\n            foo(b.value2561);\n            foo(b.value2562);\n            foo(b.value2563);\n            foo(b.value2564);\n            foo(b.value2565);\n            foo(b.value2566);\n            foo(b.value2567);\n            foo(b.value2568);\n            foo(b.value2569);\n            foo(b.value2570);\n            foo(b.value2571);\n            foo(b.value2572);\n            foo(b.value2573);\n            foo(b.value2574);\n            foo(b.value2575);\n            foo(b.value2576);\n            foo(b.value2577);\n            foo(b.value2578);\n            foo(b.value2579);\n            foo(b.value2580);\n            foo(b.value2581);\n            foo(b.value2582);\n            foo(b.value2583);\n            foo(b.value2584);\n            foo(b.value2585);\n            foo(b.value2586);\n            foo(b.value2587);\n            foo(b.value2588);\n            foo(b.value2589);\n            foo(b.value2590);\n            foo(b.value2591);\n            foo(b.value2592);\n            foo(b.value2593);\n            foo(b.value2594);\n            foo(b.value2595);\n            foo(b.value2596);\n            foo(b.value2597);\n            foo(b.value2598);\n            foo(b.value2599);\n            foo(b.value2600);\n            foo(b.value2601);\n            foo(b.value2602);\n            foo(b.value2603);\n            foo(b.value2604);\n            foo(b.value2605);\n            foo(b.value2606);\n            foo(b.value2607);\n            foo(b.value2608);\n            foo(b.value2609);\n            foo(b.value2610);\n            foo(b.value2611);\n            foo(b.value2612);\n            foo(b.value2613);\n            foo(b.value2614);\n            foo(b.value2615);\n            foo(b.value2616);\n            foo(b.value2617);\n            foo(b.value2618);\n            foo(b.value2619);\n            foo(b.value2620);\n            foo(b.value2621);\n            foo(b.value2622);\n            foo(b.value2623);\n            foo(b.value2624);\n            foo(b.value2625);\n            foo(b.value2626);\n            foo(b.value2627);\n            foo(b.value2628);\n            foo(b.value2629);\n            foo(b.value2630);\n            foo(b.value2631);\n            foo(b.value2632);\n            foo(b.value2633);\n            foo(b.value2634);\n            foo(b.value2635);\n            foo(b.value2636);\n            foo(b.value2637);\n            foo(b.value2638);\n            foo(b.value2639);\n            foo(b.value2640);\n            foo(b.value2641);\n            foo(b.value2642);\n            foo(b.value2643);\n            foo(b.value2644);\n            foo(b.value2645);\n            foo(b.value2646);\n            foo(b.value2647);\n            foo(b.value2648);\n            foo(b.value2649);\n            foo(b.value2650);\n            foo(b.value2651);\n            foo(b.value2652);\n            foo(b.value2653);\n            foo(b.value2654);\n            foo(b.value2655);\n            foo(b.value2656);\n            foo(b.value2657);\n            foo(b.value2658);\n            foo(b.value2659);\n            foo(b.value2660);\n            foo(b.value2661);\n            foo(b.value2662);\n            foo(b.value2663);\n            foo(b.value2664);\n            foo(b.value2665);\n            foo(b.value2666);\n            foo(b.value2667);\n            foo(b.value2668);\n            foo(b.value2669);\n            foo(b.value2670);\n            foo(b.value2671);\n            foo(b.value2672);\n            foo(b.value2673);\n            foo(b.value2674);\n            foo(b.value2675);\n            foo(b.value2676);\n            foo(b.value2677);\n            foo(b.value2678);\n            foo(b.value2679);\n            foo(b.value2680);\n            foo(b.value2681);\n            foo(b.value2682);\n            foo(b.value2683);\n            foo(b.value2684);\n            foo(b.value2685);\n            foo(b.value2686);\n            foo(b.value2687);\n            foo(b.value2688);\n            foo(b.value2689);\n            foo(b.value2690);\n            foo(b.value2691);\n            foo(b.value2692);\n            foo(b.value2693);\n            foo(b.value2694);\n            foo(b.value2695);\n            foo(b.value2696);\n            foo(b.value2697);\n            foo(b.value2698);\n            foo(b.value2699);\n            foo(b.value2700);\n            foo(b.value2701);\n            foo(b.value2702);\n            foo(b.value2703);\n            foo(b.value2704);\n            foo(b.value2705);\n            foo(b.value2706);\n            foo(b.value2707);\n            foo(b.value2708);\n            foo(b.value2709);\n            foo(b.value2710);\n            foo(b.value2711);\n            foo(b.value2712);\n            foo(b.value2713);\n            foo(b.value2714);\n            foo(b.value2715);\n            foo(b.value2716);\n            foo(b.value2717);\n            foo(b.value2718);\n            foo(b.value2719);\n            foo(b.value2720);\n            foo(b.value2721);\n            foo(b.value2722);\n            foo(b.value2723);\n            foo(b.value2724);\n            foo(b.value2725);\n            foo(b.value2726);\n            foo(b.value2727);\n            foo(b.value2728);\n            foo(b.value2729);\n            foo(b.value2730);\n            foo(b.value2731);\n            foo(b.value2732);\n            foo(b.value2733);\n            foo(b.value2734);\n            foo(b.value2735);\n            foo(b.value2736);\n            foo(b.value2737);\n            foo(b.value2738);\n            foo(b.value2739);\n            foo(b.value2740);\n            foo(b.value2741);\n            foo(b.value2742);\n            foo(b.value2743);\n            foo(b.value2744);\n            foo(b.value2745);\n            foo(b.value2746);\n            foo(b.value2747);\n            foo(b.value2748);\n            foo(b.value2749);\n            foo(b.value2750);\n            foo(b.value2751);\n            foo(b.value2752);\n            foo(b.value2753);\n            foo(b.value2754);\n            foo(b.value2755);\n            foo(b.value2756);\n            foo(b.value2757);\n            foo(b.value2758);\n            foo(b.value2759);\n            foo(b.value2760);\n            foo(b.value2761);\n            foo(b.value2762);\n            foo(b.value2763);\n            foo(b.value2764);\n            foo(b.value2765);\n            foo(b.value2766);\n            foo(b.value2767);\n            foo(b.value2768);\n            foo(b.value2769);\n            foo(b.value2770);\n            foo(b.value2771);\n            foo(b.value2772);\n            foo(b.value2773);\n            foo(b.value2774);\n            foo(b.value2775);\n            foo(b.value2776);\n            foo(b.value2777);\n            foo(b.value2778);\n            foo(b.value2779);\n            foo(b.value2780);\n            foo(b.value2781);\n            foo(b.value2782);\n            foo(b.value2783);\n            foo(b.value2784);\n            foo(b.value2785);\n            foo(b.value2786);\n            foo(b.value2787);\n            foo(b.value2788);\n            foo(b.value2789);\n            foo(b.value2790);\n            foo(b.value2791);\n            foo(b.value2792);\n            foo(b.value2793);\n            foo(b.value2794);\n            foo(b.value2795);\n            foo(b.value2796);\n            foo(b.value2797);\n            foo(b.value2798);\n            foo(b.value2799);\n            foo(b.value2800);\n            foo(b.value2801);\n            foo(b.value2802);\n            foo(b.value2803);\n            foo(b.value2804);\n            foo(b.value2805);\n            foo(b.value2806);\n            foo(b.value2807);\n            foo(b.value2808);\n            foo(b.value2809);\n            foo(b.value2810);\n            foo(b.value2811);\n            foo(b.value2812);\n            foo(b.value2813);\n            foo(b.value2814);\n            foo(b.value2815);\n            foo(b.value2816);\n            foo(b.value2817);\n            foo(b.value2818);\n            foo(b.value2819);\n            foo(b.value2820);\n            foo(b.value2821);\n            foo(b.value2822);\n            foo(b.value2823);\n            foo(b.value2824);\n            foo(b.value2825);\n            foo(b.value2826);\n            foo(b.value2827);\n            foo(b.value2828);\n            foo(b.value2829);\n            foo(b.value2830);\n            foo(b.value2831);\n            foo(b.value2832);\n            foo(b.value2833);\n            foo(b.value2834);\n            foo(b.value2835);\n            foo(b.value2836);\n            foo(b.value2837);\n            foo(b.value2838);\n            foo(b.value2839);\n            foo(b.value2840);\n            foo(b.value2841);\n            foo(b.value2842);\n            foo(b.value2843);\n            foo(b.value2844);\n            foo(b.value2845);\n            foo(b.value2846);\n            foo(b.value2847);\n            foo(b.value2848);\n            foo(b.value2849);\n            foo(b.value2850);\n            foo(b.value2851);\n            foo(b.value2852);\n            foo(b.value2853);\n            foo(b.value2854);\n            foo(b.value2855);\n            foo(b.value2856);\n            foo(b.value2857);\n            foo(b.value2858);\n            foo(b.value2859);\n            foo(b.value2860);\n            foo(b.value2861);\n            foo(b.value2862);\n            foo(b.value2863);\n            foo(b.value2864);\n            foo(b.value2865);\n            foo(b.value2866);\n            foo(b.value2867);\n            foo(b.value2868);\n            foo(b.value2869);\n            foo(b.value2870);\n            foo(b.value2871);\n            foo(b.value2872);\n            foo(b.value2873);\n            foo(b.value2874);\n            foo(b.value2875);\n            foo(b.value2876);\n            foo(b.value2877);\n            foo(b.value2878);\n            foo(b.value2879);\n            foo(b.value2880);\n            foo(b.value2881);\n            foo(b.value2882);\n            foo(b.value2883);\n            foo(b.value2884);\n            foo(b.value2885);\n            foo(b.value2886);\n            foo(b.value2887);\n            foo(b.value2888);\n            foo(b.value2889);\n            foo(b.value2890);\n            foo(b.value2891);\n            foo(b.value2892);\n            foo(b.value2893);\n            foo(b.value2894);\n            foo(b.value2895);\n            foo(b.value2896);\n            foo(b.value2897);\n            foo(b.value2898);\n            foo(b.value2899);\n            foo(b.value2900);\n            foo(b.value2901);\n            foo(b.value2902);\n            foo(b.value2903);\n            foo(b.value2904);\n            foo(b.value2905);\n            foo(b.value2906);\n            foo(b.value2907);\n            foo(b.value2908);\n            foo(b.value2909);\n            foo(b.value2910);\n            foo(b.value2911);\n            foo(b.value2912);\n            foo(b.value2913);\n            foo(b.value2914);\n            foo(b.value2915);\n            foo(b.value2916);\n            foo(b.value2917);\n            foo(b.value2918);\n            foo(b.value2919);\n            foo(b.value2920);\n            foo(b.value2921);\n            foo(b.value2922);\n            foo(b.value2923);\n            foo(b.value2924);\n            foo(b.value2925);\n            foo(b.value2926);\n            foo(b.value2927);\n            foo(b.value2928);\n            foo(b.value2929);\n            foo(b.value2930);\n            foo(b.value2931);\n            foo(b.value2932);\n            foo(b.value2933);\n            foo(b.value2934);\n            foo(b.value2935);\n            foo(b.value2936);\n            foo(b.value2937);\n            foo(b.value2938);\n            foo(b.value2939);\n            foo(b.value2940);\n            foo(b.value2941);\n            foo(b.value2942);\n            foo(b.value2943);\n            foo(b.value2944);\n            foo(b.value2945);\n            foo(b.value2946);\n            foo(b.value2947);\n            foo(b.value2948);\n            foo(b.value2949);\n            foo(b.value2950);\n            foo(b.value2951);\n            foo(b.value2952);\n            foo(b.value2953);\n            foo(b.value2954);\n            foo(b.value2955);\n            foo(b.value2956);\n            foo(b.value2957);\n            foo(b.value2958);\n            foo(b.value2959);\n            foo(b.value2960);\n            foo(b.value2961);\n            foo(b.value2962);\n            foo(b.value2963);\n            foo(b.value2964);\n            foo(b.value2965);\n            foo(b.value2966);\n            foo(b.value2967);\n            foo(b.value2968);\n            foo(b.value2969);\n            foo(b.value2970);\n            foo(b.value2971);\n            foo(b.value2972);\n            foo(b.value2973);\n            foo(b.value2974);\n            foo(b.value2975);\n            foo(b.value2976);\n            foo(b.value2977);\n            foo(b.value2978);\n            foo(b.value2979);\n            foo(b.value2980);\n            foo(b.value2981);\n            foo(b.value2982);\n            foo(b.value2983);\n            foo(b.value2984);\n            foo(b.value2985);\n            foo(b.value2986);\n            foo(b.value2987);\n            foo(b.value2988);\n            foo(b.value2989);\n            foo(b.value2990);\n            foo(b.value2991);\n            foo(b.value2992);\n            foo(b.value2993);\n            foo(b.value2994);\n            foo(b.value2995);\n            foo(b.value2996);\n            foo(b.value2997);\n            foo(b.value2998);\n            foo(b.value2999);\n            foo(b.value3000);\n            foo(b.value3001);\n            foo(b.value3002);\n            foo(b.value3003);\n            foo(b.value3004);\n            foo(b.value3005);\n            foo(b.value3006);\n            foo(b.value3007);\n            foo(b.value3008);\n            foo(b.value3009);\n            foo(b.value3010);\n            foo(b.value3011);\n            foo(b.value3012);\n            foo(b.value3013);\n            foo(b.value3014);\n            foo(b.value3015);\n            foo(b.value3016);\n            foo(b.value3017);\n            foo(b.value3018);\n            foo(b.value3019);\n            foo(b.value3020);\n            foo(b.value3021);\n            foo(b.value3022);\n            foo(b.value3023);\n            foo(b.value3024);\n            foo(b.value3025);\n            foo(b.value3026);\n            foo(b.value3027);\n            foo(b.value3028);\n            foo(b.value3029);\n            foo(b.value3030);\n            foo(b.value3031);\n            foo(b.value3032);\n            foo(b.value3033);\n            foo(b.value3034);\n            foo(b.value3035);\n            foo(b.value3036);\n            foo(b.value3037);\n            foo(b.value3038);\n            foo(b.value3039);\n            foo(b.value3040);\n            foo(b.value3041);\n            foo(b.value3042);\n            foo(b.value3043);\n            foo(b.value3044);\n            foo(b.value3045);\n            foo(b.value3046);\n            foo(b.value3047);\n            foo(b.value3048);\n            foo(b.value3049);\n            foo(b.value3050);\n            foo(b.value3051);\n            foo(b.value3052);\n            foo(b.value3053);\n            foo(b.value3054);\n            foo(b.value3055);\n            foo(b.value3056);\n            foo(b.value3057);\n            foo(b.value3058);\n            foo(b.value3059);\n            foo(b.value3060);\n            foo(b.value3061);\n            foo(b.value3062);\n            foo(b.value3063);\n            foo(b.value3064);\n            foo(b.value3065);\n            foo(b.value3066);\n            foo(b.value3067);\n            foo(b.value3068);\n            foo(b.value3069);\n            foo(b.value3070);\n            foo(b.value3071);\n            foo(b.value3072);\n            foo(b.value3073);\n            foo(b.value3074);\n            foo(b.value3075);\n            foo(b.value3076);\n            foo(b.value3077);\n            foo(b.value3078);\n            foo(b.value3079);\n            foo(b.value3080);\n            foo(b.value3081);\n            foo(b.value3082);\n            foo(b.value3083);\n            foo(b.value3084);\n            foo(b.value3085);\n            foo(b.value3086);\n            foo(b.value3087);\n            foo(b.value3088);\n            foo(b.value3089);\n            foo(b.value3090);\n            foo(b.value3091);\n            foo(b.value3092);\n            foo(b.value3093);\n            foo(b.value3094);\n            foo(b.value3095);\n            foo(b.value3096);\n            foo(b.value3097);\n            foo(b.value3098);\n            foo(b.value3099);\n            foo(b.value3100);\n            foo(b.value3101);\n            foo(b.value3102);\n            foo(b.value3103);\n            foo(b.value3104);\n            foo(b.value3105);\n            foo(b.value3106);\n            foo(b.value3107);\n            foo(b.value3108);\n            foo(b.value3109);\n            foo(b.value3110);\n            foo(b.value3111);\n            foo(b.value3112);\n            foo(b.value3113);\n            foo(b.value3114);\n            foo(b.value3115);\n            foo(b.value3116);\n            foo(b.value3117);\n            foo(b.value3118);\n            foo(b.value3119);\n            foo(b.value3120);\n            foo(b.value3121);\n            foo(b.value3122);\n            foo(b.value3123);\n            foo(b.value3124);\n            foo(b.value3125);\n            foo(b.value3126);\n            foo(b.value3127);\n            foo(b.value3128);\n            foo(b.value3129);\n            foo(b.value3130);\n            foo(b.value3131);\n            foo(b.value3132);\n            foo(b.value3133);\n            foo(b.value3134);\n            foo(b.value3135);\n            foo(b.value3136);\n            foo(b.value3137);\n            foo(b.value3138);\n            foo(b.value3139);\n            foo(b.value3140);\n            foo(b.value3141);\n            foo(b.value3142);\n            foo(b.value3143);\n            foo(b.value3144);\n            foo(b.value3145);\n            foo(b.value3146);\n            foo(b.value3147);\n            foo(b.value3148);\n            foo(b.value3149);\n            foo(b.value3150);\n            foo(b.value3151);\n            foo(b.value3152);\n            foo(b.value3153);\n            foo(b.value3154);\n            foo(b.value3155);\n            foo(b.value3156);\n            foo(b.value3157);\n            foo(b.value3158);\n            foo(b.value3159);\n            foo(b.value3160);\n            foo(b.value3161);\n            foo(b.value3162);\n            foo(b.value3163);\n            foo(b.value3164);\n            foo(b.value3165);\n            foo(b.value3166);\n            foo(b.value3167);\n            foo(b.value3168);\n            foo(b.value3169);\n            foo(b.value3170);\n            foo(b.value3171);\n            foo(b.value3172);\n            foo(b.value3173);\n            foo(b.value3174);\n            foo(b.value3175);\n            foo(b.value3176);\n            foo(b.value3177);\n            foo(b.value3178);\n            foo(b.value3179);\n            foo(b.value3180);\n            foo(b.value3181);\n            foo(b.value3182);\n            foo(b.value3183);\n            foo(b.value3184);\n            foo(b.value3185);\n            foo(b.value3186);\n            foo(b.value3187);\n            foo(b.value3188);\n            foo(b.value3189);\n            foo(b.value3190);\n            foo(b.value3191);\n            foo(b.value3192);\n            foo(b.value3193);\n            foo(b.value3194);\n            foo(b.value3195);\n            foo(b.value3196);\n            foo(b.value3197);\n            foo(b.value3198);\n            foo(b.value3199);\n            foo(b.value3200);\n            foo(b.value3201);\n            foo(b.value3202);\n            foo(b.value3203);\n            foo(b.value3204);\n            foo(b.value3205);\n            foo(b.value3206);\n            foo(b.value3207);\n            foo(b.value3208);\n            foo(b.value3209);\n            foo(b.value3210);\n            foo(b.value3211);\n            foo(b.value3212);\n            foo(b.value3213);\n            foo(b.value3214);\n            foo(b.value3215);\n            foo(b.value3216);\n            foo(b.value3217);\n            foo(b.value3218);\n            foo(b.value3219);\n            foo(b.value3220);\n            foo(b.value3221);\n            foo(b.value3222);\n            foo(b.value3223);\n            foo(b.value3224);\n            foo(b.value3225);\n            foo(b.value3226);\n            foo(b.value3227);\n            foo(b.value3228);\n            foo(b.value3229);\n            foo(b.value3230);\n            foo(b.value3231);\n            foo(b.value3232);\n            foo(b.value3233);\n            foo(b.value3234);\n            foo(b.value3235);\n            foo(b.value3236);\n            foo(b.value3237);\n            foo(b.value3238);\n            foo(b.value3239);\n            foo(b.value3240);\n            foo(b.value3241);\n            foo(b.value3242);\n            foo(b.value3243);\n            foo(b.value3244);\n            foo(b.value3245);\n            foo(b.value3246);\n            foo(b.value3247);\n            foo(b.value3248);\n            foo(b.value3249);\n            foo(b.value3250);\n            foo(b.value3251);\n            foo(b.value3252);\n            foo(b.value3253);\n            foo(b.value3254);\n            foo(b.value3255);\n            foo(b.value3256);\n            foo(b.value3257);\n            foo(b.value3258);\n            foo(b.value3259);\n            foo(b.value3260);\n            foo(b.value3261);\n            foo(b.value3262);\n            foo(b.value3263);\n            foo(b.value3264);\n            foo(b.value3265);\n            foo(b.value3266);\n            foo(b.value3267);\n            foo(b.value3268);\n            foo(b.value3269);\n            foo(b.value3270);\n            foo(b.value3271);\n            foo(b.value3272);\n            foo(b.value3273);\n            foo(b.value3274);\n            foo(b.value3275);\n            foo(b.value3276);\n            foo(b.value3277);\n            foo(b.value3278);\n            foo(b.value3279);\n            foo(b.value3280);\n            foo(b.value3281);\n            foo(b.value3282);\n            foo(b.value3283);\n            foo(b.value3284);\n            foo(b.value3285);\n            foo(b.value3286);\n            foo(b.value3287);\n            foo(b.value3288);\n            foo(b.value3289);\n            foo(b.value3290);\n            foo(b.value3291);\n            foo(b.value3292);\n            foo(b.value3293);\n            foo(b.value3294);\n            foo(b.value3295);\n            foo(b.value3296);\n            foo(b.value3297);\n            foo(b.value3298);\n            foo(b.value3299);\n            foo(b.value3300);\n            foo(b.value3301);\n            foo(b.value3302);\n            foo(b.value3303);\n            foo(b.value3304);\n            foo(b.value3305);\n            foo(b.value3306);\n            foo(b.value3307);\n            foo(b.value3308);\n            foo(b.value3309);\n            foo(b.value3310);\n            foo(b.value3311);\n            foo(b.value3312);\n            foo(b.value3313);\n            foo(b.value3314);\n            foo(b.value3315);\n            foo(b.value3316);\n            foo(b.value3317);\n            foo(b.value3318);\n            foo(b.value3319);\n            foo(b.value3320);\n            foo(b.value3321);\n            foo(b.value3322);\n            foo(b.value3323);\n            foo(b.value3324);\n            foo(b.value3325);\n            foo(b.value3326);\n            foo(b.value3327);\n            foo(b.value3328);\n            foo(b.value3329);\n            foo(b.value3330);\n            foo(b.value3331);\n            foo(b.value3332);\n            foo(b.value3333);\n            foo(b.value3334);\n            foo(b.value3335);\n            foo(b.value3336);\n            foo(b.value3337);\n            foo(b.value3338);\n            foo(b.value3339);\n            foo(b.value3340);\n            foo(b.value3341);\n            foo(b.value3342);\n            foo(b.value3343);\n            foo(b.value3344);\n            foo(b.value3345);\n            foo(b.value3346);\n            foo(b.value3347);\n            foo(b.value3348);\n            foo(b.value3349);\n            foo(b.value3350);\n            foo(b.value3351);\n            foo(b.value3352);\n            foo(b.value3353);\n            foo(b.value3354);\n            foo(b.value3355);\n            foo(b.value3356);\n            foo(b.value3357);\n            foo(b.value3358);\n            foo(b.value3359);\n            foo(b.value3360);\n            foo(b.value3361);\n            foo(b.value3362);\n            foo(b.value3363);\n            foo(b.value3364);\n            foo(b.value3365);\n            foo(b.value3366);\n            foo(b.value3367);\n            foo(b.value3368);\n            foo(b.value3369);\n            foo(b.value3370);\n            foo(b.value3371);\n            foo(b.value3372);\n            foo(b.value3373);\n            foo(b.value3374);\n            foo(b.value3375);\n            foo(b.value3376);\n            foo(b.value3377);\n            foo(b.value3378);\n            foo(b.value3379);\n            foo(b.value3380);\n            foo(b.value3381);\n            foo(b.value3382);\n            foo(b.value3383);\n            foo(b.value3384);\n            foo(b.value3385);\n            foo(b.value3386);\n            foo(b.value3387);\n            foo(b.value3388);\n            foo(b.value3389);\n            foo(b.value3390);\n            foo(b.value3391);\n            foo(b.value3392);\n            foo(b.value3393);\n            foo(b.value3394);\n            foo(b.value3395);\n            foo(b.value3396);\n            foo(b.value3397);\n            foo(b.value3398);\n            foo(b.value3399);\n            foo(b.value3400);\n            foo(b.value3401);\n            foo(b.value3402);\n            foo(b.value3403);\n            foo(b.value3404);\n            foo(b.value3405);\n            foo(b.value3406);\n            foo(b.value3407);\n            foo(b.value3408);\n            foo(b.value3409);\n            foo(b.value3410);\n            foo(b.value3411);\n            foo(b.value3412);\n            foo(b.value3413);\n            foo(b.value3414);\n            foo(b.value3415);\n            foo(b.value3416);\n            foo(b.value3417);\n            foo(b.value3418);\n            foo(b.value3419);\n            foo(b.value3420);\n            foo(b.value3421);\n            foo(b.value3422);\n            foo(b.value3423);\n            foo(b.value3424);\n            foo(b.value3425);\n            foo(b.value3426);\n            foo(b.value3427);\n            foo(b.value3428);\n            foo(b.value3429);\n            foo(b.value3430);\n            foo(b.value3431);\n            foo(b.value3432);\n            foo(b.value3433);\n            foo(b.value3434);\n            foo(b.value3435);\n            foo(b.value3436);\n            foo(b.value3437);\n            foo(b.value3438);\n            foo(b.value3439);\n            foo(b.value3440);\n            foo(b.value3441);\n            foo(b.value3442);\n            foo(b.value3443);\n            foo(b.value3444);\n            foo(b.value3445);\n            foo(b.value3446);\n            foo(b.value3447);\n            foo(b.value3448);\n            foo(b.value3449);\n            foo(b.value3450);\n            foo(b.value3451);\n            foo(b.value3452);\n            foo(b.value3453);\n            foo(b.value3454);\n            foo(b.value3455);\n            foo(b.value3456);\n            foo(b.value3457);\n            foo(b.value3458);\n            foo(b.value3459);\n            foo(b.value3460);\n            foo(b.value3461);\n            foo(b.value3462);\n            foo(b.value3463);\n            foo(b.value3464);\n            foo(b.value3465);\n            foo(b.value3466);\n            foo(b.value3467);\n            foo(b.value3468);\n            foo(b.value3469);\n            foo(b.value3470);\n            foo(b.value3471);\n            foo(b.value3472);\n            foo(b.value3473);\n            foo(b.value3474);\n            foo(b.value3475);\n            foo(b.value3476);\n            foo(b.value3477);\n            foo(b.value3478);\n            foo(b.value3479);\n            foo(b.value3480);\n            foo(b.value3481);\n            foo(b.value3482);\n            foo(b.value3483);\n            foo(b.value3484);\n            foo(b.value3485);\n            foo(b.value3486);\n            foo(b.value3487);\n            foo(b.value3488);\n            foo(b.value3489);\n            foo(b.value3490);\n            foo(b.value3491);\n            foo(b.value3492);\n            foo(b.value3493);\n            foo(b.value3494);\n            foo(b.value3495);\n            foo(b.value3496);\n            foo(b.value3497);\n            foo(b.value3498);\n            foo(b.value3499);\n            foo(b.value3500);\n            foo(b.value3501);\n            foo(b.value3502);\n            foo(b.value3503);\n            foo(b.value3504);\n            foo(b.value3505);\n            foo(b.value3506);\n            foo(b.value3507);\n            foo(b.value3508);\n            foo(b.value3509);\n            foo(b.value3510);\n            foo(b.value3511);\n            foo(b.value3512);\n            foo(b.value3513);\n            foo(b.value3514);\n            foo(b.value3515);\n            foo(b.value3516);\n            foo(b.value3517);\n            foo(b.value3518);\n            foo(b.value3519);\n            foo(b.value3520);\n            foo(b.value3521);\n            foo(b.value3522);\n            foo(b.value3523);\n            foo(b.value3524);\n            foo(b.value3525);\n            foo(b.value3526);\n            foo(b.value3527);\n            foo(b.value3528);\n            foo(b.value3529);\n            foo(b.value3530);\n            foo(b.value3531);\n            foo(b.value3532);\n            foo(b.value3533);\n            foo(b.value3534);\n            foo(b.value3535);\n            foo(b.value3536);\n            foo(b.value3537);\n            foo(b.value3538);\n            foo(b.value3539);\n            foo(b.value3540);\n            foo(b.value3541);\n            foo(b.value3542);\n            foo(b.value3543);\n            foo(b.value3544);\n            foo(b.value3545);\n            foo(b.value3546);\n            foo(b.value3547);\n            foo(b.value3548);\n            foo(b.value3549);\n            foo(b.value3550);\n            foo(b.value3551);\n            foo(b.value3552);\n            foo(b.value3553);\n            foo(b.value3554);\n            foo(b.value3555);\n            foo(b.value3556);\n            foo(b.value3557);\n            foo(b.value3558);\n            foo(b.value3559);\n            foo(b.value3560);\n            foo(b.value3561);\n            foo(b.value3562);\n            foo(b.value3563);\n            foo(b.value3564);\n            foo(b.value3565);\n            foo(b.value3566);\n            foo(b.value3567);\n            foo(b.value3568);\n            foo(b.value3569);\n            foo(b.value3570);\n            foo(b.value3571);\n            foo(b.value3572);\n            foo(b.value3573);\n            foo(b.value3574);\n            foo(b.value3575);\n            foo(b.value3576);\n            foo(b.value3577);\n            foo(b.value3578);\n            foo(b.value3579);\n            foo(b.value3580);\n            foo(b.value3581);\n            foo(b.value3582);\n            foo(b.value3583);\n            foo(b.value3584);\n            foo(b.value3585);\n            foo(b.value3586);\n            foo(b.value3587);\n            foo(b.value3588);\n            foo(b.value3589);\n            foo(b.value3590);\n            foo(b.value3591);\n            foo(b.value3592);\n            foo(b.value3593);\n            foo(b.value3594);\n            foo(b.value3595);\n            foo(b.value3596);\n            foo(b.value3597);\n            foo(b.value3598);\n            foo(b.value3599);\n            foo(b.value3600);\n            foo(b.value3601);\n            foo(b.value3602);\n            foo(b.value3603);\n            foo(b.value3604);\n            foo(b.value3605);\n            foo(b.value3606);\n            foo(b.value3607);\n            foo(b.value3608);\n            foo(b.value3609);\n            foo(b.value3610);\n            foo(b.value3611);\n            foo(b.value3612);\n            foo(b.value3613);\n            foo(b.value3614);\n            foo(b.value3615);\n            foo(b.value3616);\n            foo(b.value3617);\n            foo(b.value3618);\n            foo(b.value3619);\n            foo(b.value3620);\n            foo(b.value3621);\n            foo(b.value3622);\n            foo(b.value3623);\n            foo(b.value3624);\n            foo(b.value3625);\n            foo(b.value3626);\n            foo(b.value3627);\n            foo(b.value3628);\n            foo(b.value3629);\n            foo(b.value3630);\n            foo(b.value3631);\n            foo(b.value3632);\n            foo(b.value3633);\n            foo(b.value3634);\n            foo(b.value3635);\n            foo(b.value3636);\n            foo(b.value3637);\n            foo(b.value3638);\n            foo(b.value3639);\n            foo(b.value3640);\n            foo(b.value3641);\n            foo(b.value3642);\n            foo(b.value3643);\n            foo(b.value3644);\n            foo(b.value3645);\n            foo(b.value3646);\n            foo(b.value3647);\n            foo(b.value3648);\n            foo(b.value3649);\n            foo(b.value3650);\n            foo(b.value3651);\n            foo(b.value3652);\n            foo(b.value3653);\n            foo(b.value3654);\n            foo(b.value3655);\n            foo(b.value3656);\n            foo(b.value3657);\n            foo(b.value3658);\n            foo(b.value3659);\n            foo(b.value3660);\n            foo(b.value3661);\n            foo(b.value3662);\n            foo(b.value3663);\n            foo(b.value3664);\n            foo(b.value3665);\n            foo(b.value3666);\n            foo(b.value3667);\n            foo(b.value3668);\n            foo(b.value3669);\n            foo(b.value3670);\n            foo(b.value3671);\n            foo(b.value3672);\n            foo(b.value3673);\n            foo(b.value3674);\n            foo(b.value3675);\n            foo(b.value3676);\n            foo(b.value3677);\n            foo(b.value3678);\n            foo(b.value3679);\n            foo(b.value3680);\n            foo(b.value3681);\n            foo(b.value3682);\n            foo(b.value3683);\n            foo(b.value3684);\n            foo(b.value3685);\n            foo(b.value3686);\n            foo(b.value3687);\n            foo(b.value3688);\n            foo(b.value3689);\n            foo(b.value3690);\n            foo(b.value3691);\n            foo(b.value3692);\n            foo(b.value3693);\n            foo(b.value3694);\n            foo(b.value3695);\n            foo(b.value3696);\n            foo(b.value3697);\n            foo(b.value3698);\n            foo(b.value3699);\n            foo(b.value3700);\n            foo(b.value3701);\n            foo(b.value3702);\n            foo(b.value3703);\n            foo(b.value3704);\n            foo(b.value3705);\n            foo(b.value3706);\n            foo(b.value3707);\n            foo(b.value3708);\n            foo(b.value3709);\n            foo(b.value3710);\n            foo(b.value3711);\n            foo(b.value3712);\n            foo(b.value3713);\n            foo(b.value3714);\n            foo(b.value3715);\n            foo(b.value3716);\n            foo(b.value3717);\n            foo(b.value3718);\n            foo(b.value3719);\n            foo(b.value3720);\n            foo(b.value3721);\n            foo(b.value3722);\n            foo(b.value3723);\n            foo(b.value3724);\n            foo(b.value3725);\n            foo(b.value3726);\n            foo(b.value3727);\n            foo(b.value3728);\n            foo(b.value3729);\n            foo(b.value3730);\n            foo(b.value3731);\n            foo(b.value3732);\n            foo(b.value3733);\n            foo(b.value3734);\n            foo(b.value3735);\n            foo(b.value3736);\n            foo(b.value3737);\n            foo(b.value3738);\n            foo(b.value3739);\n            foo(b.value3740);\n            foo(b.value3741);\n            foo(b.value3742);\n            foo(b.value3743);\n            foo(b.value3744);\n            foo(b.value3745);\n            foo(b.value3746);\n            foo(b.value3747);\n            foo(b.value3748);\n            foo(b.value3749);\n            foo(b.value3750);\n            foo(b.value3751);\n            foo(b.value3752);\n            foo(b.value3753);\n            foo(b.value3754);\n            foo(b.value3755);\n            foo(b.value3756);\n            foo(b.value3757);\n            foo(b.value3758);\n            foo(b.value3759);\n            foo(b.value3760);\n            foo(b.value3761);\n            foo(b.value3762);\n            foo(b.value3763);\n            foo(b.value3764);\n            foo(b.value3765);\n            foo(b.value3766);\n            foo(b.value3767);\n            foo(b.value3768);\n            foo(b.value3769);\n            foo(b.value3770);\n            foo(b.value3771);\n            foo(b.value3772);\n            foo(b.value3773);\n            foo(b.value3774);\n            foo(b.value3775);\n            foo(b.value3776);\n            foo(b.value3777);\n            foo(b.value3778);\n            foo(b.value3779);\n            foo(b.value3780);\n            foo(b.value3781);\n            foo(b.value3782);\n            foo(b.value3783);\n            foo(b.value3784);\n            foo(b.value3785);\n            foo(b.value3786);\n            foo(b.value3787);\n            foo(b.value3788);\n            foo(b.value3789);\n            foo(b.value3790);\n            foo(b.value3791);\n            foo(b.value3792);\n            foo(b.value3793);\n            foo(b.value3794);\n            foo(b.value3795);\n            foo(b.value3796);\n            foo(b.value3797);\n            foo(b.value3798);\n            foo(b.value3799);\n            foo(b.value3800);\n            foo(b.value3801);\n            foo(b.value3802);\n            foo(b.value3803);\n            foo(b.value3804);\n            foo(b.value3805);\n            foo(b.value3806);\n            foo(b.value3807);\n            foo(b.value3808);\n            foo(b.value3809);\n            foo(b.value3810);\n            foo(b.value3811);\n            foo(b.value3812);\n            foo(b.value3813);\n            foo(b.value3814);\n            foo(b.value3815);\n            foo(b.value3816);\n            foo(b.value3817);\n            foo(b.value3818);\n            foo(b.value3819);\n            foo(b.value3820);\n            foo(b.value3821);\n            foo(b.value3822);\n            foo(b.value3823);\n            foo(b.value3824);\n            foo(b.value3825);\n            foo(b.value3826);\n            foo(b.value3827);\n            foo(b.value3828);\n            foo(b.value3829);\n            foo(b.value3830);\n            foo(b.value3831);\n            foo(b.value3832);\n            foo(b.value3833);\n            foo(b.value3834);\n            foo(b.value3835);\n            foo(b.value3836);\n            foo(b.value3837);\n            foo(b.value3838);\n            foo(b.value3839);\n            foo(b.value3840);\n            foo(b.value3841);\n            foo(b.value3842);\n            foo(b.value3843);\n            foo(b.value3844);\n            foo(b.value3845);\n            foo(b.value3846);\n            foo(b.value3847);\n            foo(b.value3848);\n            foo(b.value3849);\n            foo(b.value3850);\n            foo(b.value3851);\n            foo(b.value3852);\n            foo(b.value3853);\n            foo(b.value3854);\n            foo(b.value3855);\n            foo(b.value3856);\n            foo(b.value3857);\n            foo(b.value3858);\n            foo(b.value3859);\n            foo(b.value3860);\n            foo(b.value3861);\n            foo(b.value3862);\n            foo(b.value3863);\n            foo(b.value3864);\n            foo(b.value3865);\n            foo(b.value3866);\n            foo(b.value3867);\n            foo(b.value3868);\n            foo(b.value3869);\n            foo(b.value3870);\n            foo(b.value3871);\n            foo(b.value3872);\n            foo(b.value3873);\n            foo(b.value3874);\n            foo(b.value3875);\n            foo(b.value3876);\n            foo(b.value3877);\n            foo(b.value3878);\n            foo(b.value3879);\n            foo(b.value3880);\n            foo(b.value3881);\n            foo(b.value3882);\n            foo(b.value3883);\n            foo(b.value3884);\n            foo(b.value3885);\n            foo(b.value3886);\n            foo(b.value3887);\n            foo(b.value3888);\n            foo(b.value3889);\n            foo(b.value3890);\n            foo(b.value3891);\n            foo(b.value3892);\n            foo(b.value3893);\n            foo(b.value3894);\n            foo(b.value3895);\n            foo(b.value3896);\n            foo(b.value3897);\n            foo(b.value3898);\n            foo(b.value3899);\n            foo(b.value3900);\n            foo(b.value3901);\n            foo(b.value3902);\n            foo(b.value3903);\n            foo(b.value3904);\n            foo(b.value3905);\n            foo(b.value3906);\n            foo(b.value3907);\n            foo(b.value3908);\n            foo(b.value3909);\n            foo(b.value3910);\n            foo(b.value3911);\n            foo(b.value3912);\n            foo(b.value3913);\n            foo(b.value3914);\n            foo(b.value3915);\n            foo(b.value3916);\n            foo(b.value3917);\n            foo(b.value3918);\n            foo(b.value3919);\n            foo(b.value3920);\n            foo(b.value3921);\n            foo(b.value3922);\n            foo(b.value3923);\n            foo(b.value3924);\n            foo(b.value3925);\n            foo(b.value3926);\n            foo(b.value3927);\n            foo(b.value3928);\n            foo(b.value3929);\n            foo(b.value3930);\n            foo(b.value3931);\n            foo(b.value3932);\n            foo(b.value3933);\n            foo(b.value3934);\n            foo(b.value3935);\n            foo(b.value3936);\n            foo(b.value3937);\n            foo(b.value3938);\n            foo(b.value3939);\n            foo(b.value3940);\n            foo(b.value3941);\n            foo(b.value3942);\n            foo(b.value3943);\n            foo(b.value3944);\n            foo(b.value3945);\n            foo(b.value3946);\n            foo(b.value3947);\n            foo(b.value3948);\n            foo(b.value3949);\n            foo(b.value3950);\n            foo(b.value3951);\n            foo(b.value3952);\n            foo(b.value3953);\n            foo(b.value3954);\n            foo(b.value3955);\n            foo(b.value3956);\n            foo(b.value3957);\n            foo(b.value3958);\n            foo(b.value3959);\n            foo(b.value3960);\n            foo(b.value3961);\n            foo(b.value3962);\n            foo(b.value3963);\n            foo(b.value3964);\n            foo(b.value3965);\n            foo(b.value3966);\n            foo(b.value3967);\n            foo(b.value3968);\n            foo(b.value3969);\n            foo(b.value3970);\n            foo(b.value3971);\n            foo(b.value3972);\n            foo(b.value3973);\n            foo(b.value3974);\n            foo(b.value3975);\n            foo(b.value3976);\n            foo(b.value3977);\n            foo(b.value3978);\n            foo(b.value3979);\n            foo(b.value3980);\n            foo(b.value3981);\n            foo(b.value3982);\n            foo(b.value3983);\n            foo(b.value3984);\n            foo(b.value3985);\n            foo(b.value3986);\n            foo(b.value3987);\n            foo(b.value3988);\n            foo(b.value3989);\n            foo(b.value3990);\n            foo(b.value3991);\n            foo(b.value3992);\n            foo(b.value3993);\n            foo(b.value3994);\n            foo(b.value3995);\n            foo(b.value3996);\n            foo(b.value3997);\n            foo(b.value3998);\n            foo(b.value3999);\n            foo(b.value4000);\n            foo(b.value4001);\n            foo(b.value4002);\n            foo(b.value4003);\n            foo(b.value4004);\n            foo(b.value4005);\n            foo(b.value4006);\n            foo(b.value4007);\n            foo(b.value4008);\n            foo(b.value4009);\n            foo(b.value4010);\n            foo(b.value4011);\n            foo(b.value4012);\n            foo(b.value4013);\n            foo(b.value4014);\n            foo(b.value4015);\n            foo(b.value4016);\n            foo(b.value4017);\n            foo(b.value4018);\n            foo(b.value4019);\n            foo(b.value4020);\n            foo(b.value4021);\n            foo(b.value4022);\n            foo(b.value4023);\n            foo(b.value4024);\n            foo(b.value4025);\n            foo(b.value4026);\n            foo(b.value4027);\n            foo(b.value4028);\n            foo(b.value4029);\n            foo(b.value4030);\n            foo(b.value4031);\n            foo(b.value4032);\n            foo(b.value4033);\n            foo(b.value4034);\n            foo(b.value4035);\n            foo(b.value4036);\n            foo(b.value4037);\n            foo(b.value4038);\n            foo(b.value4039);\n            foo(b.value4040);\n            foo(b.value4041);\n            foo(b.value4042);\n            foo(b.value4043);\n            foo(b.value4044);\n            foo(b.value4045);\n            foo(b.value4046);\n            foo(b.value4047);\n            foo(b.value4048);\n            foo(b.value4049);\n            foo(b.value4050);\n            foo(b.value4051);\n            foo(b.value4052);\n            foo(b.value4053);\n            foo(b.value4054);\n            foo(b.value4055);\n            foo(b.value4056);\n            foo(b.value4057);\n            foo(b.value4058);\n            foo(b.value4059);\n            foo(b.value4060);\n            foo(b.value4061);\n            foo(b.value4062);\n            foo(b.value4063);\n            foo(b.value4064);\n            foo(b.value4065);\n            foo(b.value4066);\n            foo(b.value4067);\n            foo(b.value4068);\n            foo(b.value4069);\n            foo(b.value4070);\n            foo(b.value4071);\n            foo(b.value4072);\n            foo(b.value4073);\n            foo(b.value4074);\n            foo(b.value4075);\n            foo(b.value4076);\n            foo(b.value4077);\n            foo(b.value4078);\n            foo(b.value4079);\n            foo(b.value4080);\n            foo(b.value4081);\n            foo(b.value4082);\n            foo(b.value4083);\n            foo(b.value4084);\n            foo(b.value4085);\n            foo(b.value4086);\n            foo(b.value4087);\n            foo(b.value4088);\n            foo(b.value4089);\n            foo(b.value4090);\n            foo(b.value4091);\n            foo(b.value4092);\n            foo(b.value4093);\n            foo(b.value4094);\n            foo(b.value4095);\n            foo(b.value4096);\n            foo(b.value4097);\n            foo(b.value4098);\n            foo(b.value4099);\n            foo(b.value4100);\n            foo(b.value4101);\n            foo(b.value4102);\n            foo(b.value4103);\n            foo(b.value4104);\n            foo(b.value4105);\n            foo(b.value4106);\n            foo(b.value4107);\n            foo(b.value4108);\n            foo(b.value4109);\n            foo(b.value4110);\n            foo(b.value4111);\n            foo(b.value4112);\n            foo(b.value4113);\n            foo(b.value4114);\n            foo(b.value4115);\n            foo(b.value4116);\n            foo(b.value4117);\n            foo(b.value4118);\n            foo(b.value4119);\n            foo(b.value4120);\n            foo(b.value4121);\n            foo(b.value4122);\n            foo(b.value4123);\n            foo(b.value4124);\n            foo(b.value4125);\n            foo(b.value4126);\n            foo(b.value4127);\n            foo(b.value4128);\n            foo(b.value4129);\n            foo(b.value4130);\n            foo(b.value4131);\n            foo(b.value4132);\n            foo(b.value4133);\n            foo(b.value4134);\n            foo(b.value4135);\n            foo(b.value4136);\n            foo(b.value4137);\n            foo(b.value4138);\n            foo(b.value4139);\n            foo(b.value4140);\n            foo(b.value4141);\n            foo(b.value4142);\n            foo(b.value4143);\n            foo(b.value4144);\n            foo(b.value4145);\n            foo(b.value4146);\n            foo(b.value4147);\n            foo(b.value4148);\n            foo(b.value4149);\n            foo(b.value4150);\n            foo(b.value4151);\n            foo(b.value4152);\n            foo(b.value4153);\n            foo(b.value4154);\n            foo(b.value4155);\n            foo(b.value4156);\n            foo(b.value4157);\n            foo(b.value4158);\n            foo(b.value4159);\n            foo(b.value4160);\n            foo(b.value4161);\n            foo(b.value4162);\n            foo(b.value4163);\n            foo(b.value4164);\n            foo(b.value4165);\n            foo(b.value4166);\n            foo(b.value4167);\n            foo(b.value4168);\n            foo(b.value4169);\n            foo(b.value4170);\n            foo(b.value4171);\n            foo(b.value4172);\n            foo(b.value4173);\n            foo(b.value4174);\n            foo(b.value4175);\n            foo(b.value4176);\n            foo(b.value4177);\n            foo(b.value4178);\n            foo(b.value4179);\n            foo(b.value4180);\n            foo(b.value4181);\n            foo(b.value4182);\n            foo(b.value4183);\n            foo(b.value4184);\n            foo(b.value4185);\n            foo(b.value4186);\n            foo(b.value4187);\n            foo(b.value4188);\n            foo(b.value4189);\n            foo(b.value4190);\n            foo(b.value4191);\n            foo(b.value4192);\n            foo(b.value4193);\n            foo(b.value4194);\n            foo(b.value4195);\n            foo(b.value4196);\n            foo(b.value4197);\n            foo(b.value4198);\n            foo(b.value4199);\n            foo(b.value4200);\n            foo(b.value4201);\n            foo(b.value4202);\n            foo(b.value4203);\n            foo(b.value4204);\n            foo(b.value4205);\n            foo(b.value4206);\n            foo(b.value4207);\n            foo(b.value4208);\n            foo(b.value4209);\n            foo(b.value4210);\n            foo(b.value4211);\n            foo(b.value4212);\n            foo(b.value4213);\n            foo(b.value4214);\n            foo(b.value4215);\n            foo(b.value4216);\n            foo(b.value4217);\n            foo(b.value4218);\n            foo(b.value4219);\n            foo(b.value4220);\n            foo(b.value4221);\n            foo(b.value4222);\n            foo(b.value4223);\n            foo(b.value4224);\n            foo(b.value4225);\n            foo(b.value4226);\n            foo(b.value4227);\n            foo(b.value4228);\n            foo(b.value4229);\n            foo(b.value4230);\n            foo(b.value4231);\n            foo(b.value4232);\n            foo(b.value4233);\n            foo(b.value4234);\n            foo(b.value4235);\n            foo(b.value4236);\n            foo(b.value4237);\n            foo(b.value4238);\n            foo(b.value4239);\n            foo(b.value4240);\n            foo(b.value4241);\n            foo(b.value4242);\n            foo(b.value4243);\n            foo(b.value4244);\n            foo(b.value4245);\n            foo(b.value4246);\n            foo(b.value4247);\n            foo(b.value4248);\n            foo(b.value4249);\n            foo(b.value4250);\n            foo(b.value4251);\n            foo(b.value4252);\n            foo(b.value4253);\n            foo(b.value4254);\n            foo(b.value4255);\n            foo(b.value4256);\n            foo(b.value4257);\n            foo(b.value4258);\n            foo(b.value4259);\n            foo(b.value4260);\n            foo(b.value4261);\n            foo(b.value4262);\n            foo(b.value4263);\n            foo(b.value4264);\n            foo(b.value4265);\n            foo(b.value4266);\n            foo(b.value4267);\n            foo(b.value4268);\n            foo(b.value4269);\n            foo(b.value4270);\n            foo(b.value4271);\n            foo(b.value4272);\n            foo(b.value4273);\n            foo(b.value4274);\n            foo(b.value4275);\n            foo(b.value4276);\n            foo(b.value4277);\n            foo(b.value4278);\n            foo(b.value4279);\n            foo(b.value4280);\n            foo(b.value4281);\n            foo(b.value4282);\n            foo(b.value4283);\n            foo(b.value4284);\n            foo(b.value4285);\n            foo(b.value4286);\n            foo(b.value4287);\n            foo(b.value4288);\n            foo(b.value4289);\n            foo(b.value4290);\n            foo(b.value4291);\n            foo(b.value4292);\n            foo(b.value4293);\n            foo(b.value4294);\n            foo(b.value4295);\n            foo(b.value4296);\n            foo(b.value4297);\n            foo(b.value4298);\n            foo(b.value4299);\n            foo(b.value4300);\n            foo(b.value4301);\n            foo(b.value4302);\n            foo(b.value4303);\n            foo(b.value4304);\n            foo(b.value4305);\n            foo(b.value4306);\n            foo(b.value4307);\n            foo(b.value4308);\n            foo(b.value4309);\n            foo(b.value4310);\n            foo(b.value4311);\n            foo(b.value4312);\n            foo(b.value4313);\n            foo(b.value4314);\n            foo(b.value4315);\n            foo(b.value4316);\n            foo(b.value4317);\n            foo(b.value4318);\n            foo(b.value4319);\n            foo(b.value4320);\n            foo(b.value4321);\n            foo(b.value4322);\n            foo(b.value4323);\n            foo(b.value4324);\n            foo(b.value4325);\n            foo(b.value4326);\n            foo(b.value4327);\n            foo(b.value4328);\n            foo(b.value4329);\n            foo(b.value4330);\n            foo(b.value4331);\n            foo(b.value4332);\n            foo(b.value4333);\n            foo(b.value4334);\n            foo(b.value4335);\n            foo(b.value4336);\n            foo(b.value4337);\n            foo(b.value4338);\n            foo(b.value4339);\n            foo(b.value4340);\n            foo(b.value4341);\n            foo(b.value4342);\n            foo(b.value4343);\n            foo(b.value4344);\n            foo(b.value4345);\n            foo(b.value4346);\n            foo(b.value4347);\n            foo(b.value4348);\n            foo(b.value4349);\n            foo(b.value4350);\n            foo(b.value4351);\n            foo(b.value4352);\n            foo(b.value4353);\n            foo(b.value4354);\n            foo(b.value4355);\n            foo(b.value4356);\n            foo(b.value4357);\n            foo(b.value4358);\n            foo(b.value4359);\n            foo(b.value4360);\n            foo(b.value4361);\n            foo(b.value4362);\n            foo(b.value4363);\n            foo(b.value4364);\n            foo(b.value4365);\n            foo(b.value4366);\n            foo(b.value4367);\n            foo(b.value4368);\n            foo(b.value4369);\n            foo(b.value4370);\n            foo(b.value4371);\n            foo(b.value4372);\n            foo(b.value4373);\n            foo(b.value4374);\n            foo(b.value4375);\n            foo(b.value4376);\n            foo(b.value4377);\n            foo(b.value4378);\n            foo(b.value4379);\n            foo(b.value4380);\n            foo(b.value4381);\n            foo(b.value4382);\n            foo(b.value4383);\n            foo(b.value4384);\n            foo(b.value4385);\n            foo(b.value4386);\n            foo(b.value4387);\n            foo(b.value4388);\n            foo(b.value4389);\n            foo(b.value4390);\n            foo(b.value4391);\n            foo(b.value4392);\n            foo(b.value4393);\n            foo(b.value4394);\n            foo(b.value4395);\n            foo(b.value4396);\n            foo(b.value4397);\n            foo(b.value4398);\n            foo(b.value4399);\n            foo(b.value4400);\n            foo(b.value4401);\n            foo(b.value4402);\n            foo(b.value4403);\n            foo(b.value4404);\n            foo(b.value4405);\n            foo(b.value4406);\n            foo(b.value4407);\n            foo(b.value4408);\n            foo(b.value4409);\n            foo(b.value4410);\n            foo(b.value4411);\n            foo(b.value4412);\n            foo(b.value4413);\n            foo(b.value4414);\n            foo(b.value4415);\n            foo(b.value4416);\n            foo(b.value4417);\n            foo(b.value4418);\n            foo(b.value4419);\n            foo(b.value4420);\n            foo(b.value4421);\n            foo(b.value4422);\n            foo(b.value4423);\n            foo(b.value4424);\n            foo(b.value4425);\n            foo(b.value4426);\n            foo(b.value4427);\n            foo(b.value4428);\n            foo(b.value4429);\n            foo(b.value4430);\n            foo(b.value4431);\n            foo(b.value4432);\n            foo(b.value4433);\n            foo(b.value4434);\n            foo(b.value4435);\n            foo(b.value4436);\n            foo(b.value4437);\n            foo(b.value4438);\n            foo(b.value4439);\n            foo(b.value4440);\n            foo(b.value4441);\n            foo(b.value4442);\n            foo(b.value4443);\n            foo(b.value4444);\n            foo(b.value4445);\n            foo(b.value4446);\n            foo(b.value4447);\n            foo(b.value4448);\n            foo(b.value4449);\n            foo(b.value4450);\n            foo(b.value4451);\n            foo(b.value4452);\n            foo(b.value4453);\n            foo(b.value4454);\n            foo(b.value4455);\n            foo(b.value4456);\n            foo(b.value4457);\n            foo(b.value4458);\n            foo(b.value4459);\n            foo(b.value4460);\n            foo(b.value4461);\n            foo(b.value4462);\n            foo(b.value4463);\n            foo(b.value4464);\n            foo(b.value4465);\n            foo(b.value4466);\n            foo(b.value4467);\n            foo(b.value4468);\n            foo(b.value4469);\n            foo(b.value4470);\n            foo(b.value4471);\n            foo(b.value4472);\n            foo(b.value4473);\n            foo(b.value4474);\n            foo(b.value4475);\n            foo(b.value4476);\n            foo(b.value4477);\n            foo(b.value4478);\n            foo(b.value4479);\n            foo(b.value4480);\n            foo(b.value4481);\n            foo(b.value4482);\n            foo(b.value4483);\n            foo(b.value4484);\n            foo(b.value4485);\n            foo(b.value4486);\n            foo(b.value4487);\n            foo(b.value4488);\n            foo(b.value4489);\n            foo(b.value4490);\n            foo(b.value4491);\n            foo(b.value4492);\n            foo(b.value4493);\n            foo(b.value4494);\n            foo(b.value4495);\n            foo(b.value4496);\n            foo(b.value4497);\n            foo(b.value4498);\n            foo(b.value4499);\n            foo(b.value4500);\n            foo(b.value4501);\n            foo(b.value4502);\n            foo(b.value4503);\n            foo(b.value4504);\n            foo(b.value4505);\n            foo(b.value4506);\n            foo(b.value4507);\n            foo(b.value4508);\n            foo(b.value4509);\n            foo(b.value4510);\n            foo(b.value4511);\n            foo(b.value4512);\n            foo(b.value4513);\n            foo(b.value4514);\n            foo(b.value4515);\n            foo(b.value4516);\n            foo(b.value4517);\n            foo(b.value4518);\n            foo(b.value4519);\n            foo(b.value4520);\n            foo(b.value4521);\n            foo(b.value4522);\n            foo(b.value4523);\n            foo(b.value4524);\n            foo(b.value4525);\n            foo(b.value4526);\n            foo(b.value4527);\n            foo(b.value4528);\n            foo(b.value4529);\n            foo(b.value4530);\n            foo(b.value4531);\n            foo(b.value4532);\n            foo(b.value4533);\n            foo(b.value4534);\n            foo(b.value4535);\n            foo(b.value4536);\n            foo(b.value4537);\n            foo(b.value4538);\n            foo(b.value4539);\n            foo(b.value4540);\n            foo(b.value4541);\n            foo(b.value4542);\n            foo(b.value4543);\n            foo(b.value4544);\n            foo(b.value4545);\n            foo(b.value4546);\n            foo(b.value4547);\n            foo(b.value4548);\n            foo(b.value4549);\n            foo(b.value4550);\n            foo(b.value4551);\n            foo(b.value4552);\n            foo(b.value4553);\n            foo(b.value4554);\n            foo(b.value4555);\n            foo(b.value4556);\n            foo(b.value4557);\n            foo(b.value4558);\n            foo(b.value4559);\n            foo(b.value4560);\n            foo(b.value4561);\n            foo(b.value4562);\n            foo(b.value4563);\n            foo(b.value4564);\n            foo(b.value4565);\n            foo(b.value4566);\n            foo(b.value4567);\n            foo(b.value4568);\n            foo(b.value4569);\n            foo(b.value4570);\n            foo(b.value4571);\n            foo(b.value4572);\n            foo(b.value4573);\n            foo(b.value4574);\n            foo(b.value4575);\n            foo(b.value4576);\n            foo(b.value4577);\n            foo(b.value4578);\n            foo(b.value4579);\n            foo(b.value4580);\n            foo(b.value4581);\n            foo(b.value4582);\n            foo(b.value4583);\n            foo(b.value4584);\n            foo(b.value4585);\n            foo(b.value4586);\n            foo(b.value4587);\n            foo(b.value4588);\n            foo(b.value4589);\n            foo(b.value4590);\n            foo(b.value4591);\n            foo(b.value4592);\n            foo(b.value4593);\n            foo(b.value4594);\n            foo(b.value4595);\n            foo(b.value4596);\n            foo(b.value4597);\n            foo(b.value4598);\n            foo(b.value4599);\n            foo(b.value4600);\n            foo(b.value4601);\n            foo(b.value4602);\n            foo(b.value4603);\n            foo(b.value4604);\n            foo(b.value4605);\n            foo(b.value4606);\n            foo(b.value4607);\n            foo(b.value4608);\n            foo(b.value4609);\n            foo(b.value4610);\n            foo(b.value4611);\n            foo(b.value4612);\n            foo(b.value4613);\n            foo(b.value4614);\n            foo(b.value4615);\n            foo(b.value4616);\n            foo(b.value4617);\n            foo(b.value4618);\n            foo(b.value4619);\n            foo(b.value4620);\n            foo(b.value4621);\n            foo(b.value4622);\n            foo(b.value4623);\n            foo(b.value4624);\n            foo(b.value4625);\n            foo(b.value4626);\n            foo(b.value4627);\n            foo(b.value4628);\n            foo(b.value4629);\n            foo(b.value4630);\n            foo(b.value4631);\n            foo(b.value4632);\n            foo(b.value4633);\n            foo(b.value4634);\n            foo(b.value4635);\n            foo(b.value4636);\n            foo(b.value4637);\n            foo(b.value4638);\n            foo(b.value4639);\n            foo(b.value4640);\n            foo(b.value4641);\n            foo(b.value4642);\n            foo(b.value4643);\n            foo(b.value4644);\n            foo(b.value4645);\n            foo(b.value4646);\n            foo(b.value4647);\n            foo(b.value4648);\n            foo(b.value4649);\n            foo(b.value4650);\n            foo(b.value4651);\n            foo(b.value4652);\n            foo(b.value4653);\n            foo(b.value4654);\n            foo(b.value4655);\n            foo(b.value4656);\n            foo(b.value4657);\n            foo(b.value4658);\n            foo(b.value4659);\n            foo(b.value4660);\n            foo(b.value4661);\n            foo(b.value4662);\n            foo(b.value4663);\n            foo(b.value4664);\n            foo(b.value4665);\n            foo(b.value4666);\n            foo(b.value4667);\n            foo(b.value4668);\n            foo(b.value4669);\n            foo(b.value4670);\n            foo(b.value4671);\n            foo(b.value4672);\n            foo(b.value4673);\n            foo(b.value4674);\n            foo(b.value4675);\n            foo(b.value4676);\n            foo(b.value4677);\n            foo(b.value4678);\n            foo(b.value4679);\n            foo(b.value4680);\n            foo(b.value4681);\n            foo(b.value4682);\n            foo(b.value4683);\n            foo(b.value4684);\n            foo(b.value4685);\n            foo(b.value4686);\n            foo(b.value4687);\n            foo(b.value4688);\n            foo(b.value4689);\n            foo(b.value4690);\n            foo(b.value4691);\n            foo(b.value4692);\n            foo(b.value4693);\n            foo(b.value4694);\n            foo(b.value4695);\n            foo(b.value4696);\n            foo(b.value4697);\n            foo(b.value4698);\n            foo(b.value4699);\n            foo(b.value4700);\n            foo(b.value4701);\n            foo(b.value4702);\n            foo(b.value4703);\n            foo(b.value4704);\n            foo(b.value4705);\n            foo(b.value4706);\n            foo(b.value4707);\n            foo(b.value4708);\n            foo(b.value4709);\n            foo(b.value4710);\n            foo(b.value4711);\n            foo(b.value4712);\n            foo(b.value4713);\n            foo(b.value4714);\n            foo(b.value4715);\n            foo(b.value4716);\n            foo(b.value4717);\n            foo(b.value4718);\n            foo(b.value4719);\n            foo(b.value4720);\n            foo(b.value4721);\n            foo(b.value4722);\n            foo(b.value4723);\n            foo(b.value4724);\n            foo(b.value4725);\n            foo(b.value4726);\n            foo(b.value4727);\n            foo(b.value4728);\n            foo(b.value4729);\n            foo(b.value4730);\n            foo(b.value4731);\n            foo(b.value4732);\n            foo(b.value4733);\n            foo(b.value4734);\n            foo(b.value4735);\n            foo(b.value4736);\n            foo(b.value4737);\n            foo(b.value4738);\n            foo(b.value4739);\n            foo(b.value4740);\n            foo(b.value4741);\n            foo(b.value4742);\n            foo(b.value4743);\n            foo(b.value4744);\n            foo(b.value4745);\n            foo(b.value4746);\n            foo(b.value4747);\n            foo(b.value4748);\n            foo(b.value4749);\n            foo(b.value4750);\n            foo(b.value4751);\n            foo(b.value4752);\n            foo(b.value4753);\n            foo(b.value4754);\n            foo(b.value4755);\n            foo(b.value4756);\n            foo(b.value4757);\n            foo(b.value4758);\n            foo(b.value4759);\n            foo(b.value4760);\n            foo(b.value4761);\n            foo(b.value4762);\n            foo(b.value4763);\n            foo(b.value4764);\n            foo(b.value4765);\n            foo(b.value4766);\n            foo(b.value4767);\n            foo(b.value4768);\n            foo(b.value4769);\n            foo(b.value4770);\n            foo(b.value4771);\n            foo(b.value4772);\n            foo(b.value4773);\n            foo(b.value4774);\n            foo(b.value4775);\n            foo(b.value4776);\n            foo(b.value4777);\n            foo(b.value4778);\n            foo(b.value4779);\n            foo(b.value4780);\n            foo(b.value4781);\n            foo(b.value4782);\n            foo(b.value4783);\n            foo(b.value4784);\n            foo(b.value4785);\n            foo(b.value4786);\n            foo(b.value4787);\n            foo(b.value4788);\n            foo(b.value4789);\n            foo(b.value4790);\n            foo(b.value4791);\n            foo(b.value4792);\n            foo(b.value4793);\n            foo(b.value4794);\n            foo(b.value4795);\n            foo(b.value4796);\n            foo(b.value4797);\n            foo(b.value4798);\n            foo(b.value4799);\n            foo(b.value4800);\n            foo(b.value4801);\n            foo(b.value4802);\n            foo(b.value4803);\n            foo(b.value4804);\n            foo(b.value4805);\n            foo(b.value4806);\n            foo(b.value4807);\n            foo(b.value4808);\n            foo(b.value4809);\n            foo(b.value4810);\n            foo(b.value4811);\n            foo(b.value4812);\n            foo(b.value4813);\n            foo(b.value4814);\n            foo(b.value4815);\n            foo(b.value4816);\n            foo(b.value4817);\n            foo(b.value4818);\n            foo(b.value4819);\n            foo(b.value4820);\n            foo(b.value4821);\n            foo(b.value4822);\n            foo(b.value4823);\n            foo(b.value4824);\n            foo(b.value4825);\n            foo(b.value4826);\n            foo(b.value4827);\n            foo(b.value4828);\n            foo(b.value4829);\n            foo(b.value4830);\n            foo(b.value4831);\n            foo(b.value4832);\n            foo(b.value4833);\n            foo(b.value4834);\n            foo(b.value4835);\n            foo(b.value4836);\n            foo(b.value4837);\n            foo(b.value4838);\n            foo(b.value4839);\n            foo(b.value4840);\n            foo(b.value4841);\n            foo(b.value4842);\n            foo(b.value4843);\n            foo(b.value4844);\n            foo(b.value4845);\n            foo(b.value4846);\n            foo(b.value4847);\n            foo(b.value4848);\n            foo(b.value4849);\n            foo(b.value4850);\n            foo(b.value4851);\n            foo(b.value4852);\n            foo(b.value4853);\n            foo(b.value4854);\n            foo(b.value4855);\n            foo(b.value4856);\n            foo(b.value4857);\n            foo(b.value4858);\n            foo(b.value4859);\n            foo(b.value4860);\n            foo(b.value4861);\n            foo(b.value4862);\n            foo(b.value4863);\n            foo(b.value4864);\n            foo(b.value4865);\n            foo(b.value4866);\n            foo(b.value4867);\n            foo(b.value4868);\n            foo(b.value4869);\n            foo(b.value4870);\n            foo(b.value4871);\n            foo(b.value4872);\n            foo(b.value4873);\n            foo(b.value4874);\n            foo(b.value4875);\n            foo(b.value4876);\n            foo(b.value4877);\n            foo(b.value4878);\n            foo(b.value4879);\n            foo(b.value4880);\n            foo(b.value4881);\n            foo(b.value4882);\n            foo(b.value4883);\n            foo(b.value4884);\n            foo(b.value4885);\n            foo(b.value4886);\n            foo(b.value4887);\n            foo(b.value4888);\n            foo(b.value4889);\n            foo(b.value4890);\n            foo(b.value4891);\n            foo(b.value4892);\n            foo(b.value4893);\n            foo(b.value4894);\n            foo(b.value4895);\n            foo(b.value4896);\n            foo(b.value4897);\n            foo(b.value4898);\n            foo(b.value4899);\n            foo(b.value4900);\n            foo(b.value4901);\n            foo(b.value4902);\n            foo(b.value4903);\n            foo(b.value4904);\n            foo(b.value4905);\n            foo(b.value4906);\n            foo(b.value4907);\n            foo(b.value4908);\n            foo(b.value4909);\n            foo(b.value4910);\n            foo(b.value4911);\n            foo(b.value4912);\n            foo(b.value4913);\n            foo(b.value4914);\n            foo(b.value4915);\n            foo(b.value4916);\n            foo(b.value4917);\n            foo(b.value4918);\n            foo(b.value4919);\n            foo(b.value4920);\n            foo(b.value4921);\n            foo(b.value4922);\n            foo(b.value4923);\n            foo(b.value4924);\n            foo(b.value4925);\n            foo(b.value4926);\n            foo(b.value4927);\n            foo(b.value4928);\n            foo(b.value4929);\n            foo(b.value4930);\n            foo(b.value4931);\n            foo(b.value4932);\n            foo(b.value4933);\n            foo(b.value4934);\n            foo(b.value4935);\n            foo(b.value4936);\n            foo(b.value4937);\n            foo(b.value4938);\n            foo(b.value4939);\n            foo(b.value4940);\n            foo(b.value4941);\n            foo(b.value4942);\n            foo(b.value4943);\n            foo(b.value4944);\n            foo(b.value4945);\n            foo(b.value4946);\n            foo(b.value4947);\n            foo(b.value4948);\n            foo(b.value4949);\n            foo(b.value4950);\n            foo(b.value4951);\n            foo(b.value4952);\n            foo(b.value4953);\n            foo(b.value4954);\n            foo(b.value4955);\n            foo(b.value4956);\n            foo(b.value4957);\n            foo(b.value4958);\n            foo(b.value4959);\n            foo(b.value4960);\n            foo(b.value4961);\n            foo(b.value4962);\n            foo(b.value4963);\n            foo(b.value4964);\n            foo(b.value4965);\n            foo(b.value4966);\n            foo(b.value4967);\n            foo(b.value4968);\n            foo(b.value4969);\n            foo(b.value4970);\n            foo(b.value4971);\n            foo(b.value4972);\n            foo(b.value4973);\n            foo(b.value4974);\n            foo(b.value4975);\n            foo(b.value4976);\n            foo(b.value4977);\n            foo(b.value4978);\n            foo(b.value4979);\n            foo(b.value4980);\n            foo(b.value4981);\n            foo(b.value4982);\n            foo(b.value4983);\n            foo(b.value4984);\n            foo(b.value4985);\n            foo(b.value4986);\n            foo(b.value4987);\n            foo(b.value4988);\n            foo(b.value4989);\n            foo(b.value4990);\n            foo(b.value4991);\n            foo(b.value4992);\n            foo(b.value4993);\n            foo(b.value4994);\n            foo(b.value4995);\n            foo(b.value4996);\n            foo(b.value4997);\n            foo(b.value4998);\n            foo(b.value4999);\n            foo(b.value5000);\n            foo(b.value5001);\n            foo(b.value5002);\n            foo(b.value5003);\n            foo(b.value5004);\n            foo(b.value5005);\n            foo(b.value5006);\n            foo(b.value5007);\n            foo(b.value5008);\n            foo(b.value5009);\n            foo(b.value5010);\n            foo(b.value5011);\n            foo(b.value5012);\n            foo(b.value5013);\n            foo(b.value5014);\n            foo(b.value5015);\n            foo(b.value5016);\n            foo(b.value5017);\n            foo(b.value5018);\n            foo(b.value5019);\n            foo(b.value5020);\n            foo(b.value5021);\n            foo(b.value5022);\n            foo(b.value5023);\n            foo(b.value5024);\n            foo(b.value5025);\n            foo(b.value5026);\n            foo(b.value5027);\n            foo(b.value5028);\n            foo(b.value5029);\n            foo(b.value5030);\n            foo(b.value5031);\n            foo(b.value5032);\n            foo(b.value5033);\n            foo(b.value5034);\n            foo(b.value5035);\n            foo(b.value5036);\n            foo(b.value5037);\n            foo(b.value5038);\n            foo(b.value5039);\n            foo(b.value5040);\n            foo(b.value5041);\n            foo(b.value5042);\n            foo(b.value5043);\n            foo(b.value5044);\n            foo(b.value5045);\n            foo(b.value5046);\n            foo(b.value5047);\n            foo(b.value5048);\n            foo(b.value5049);\n            foo(b.value5050);\n            foo(b.value5051);\n            foo(b.value5052);\n            foo(b.value5053);\n            foo(b.value5054);\n            foo(b.value5055);\n            foo(b.value5056);\n            foo(b.value5057);\n            foo(b.value5058);\n            foo(b.value5059);\n            foo(b.value5060);\n            foo(b.value5061);\n            foo(b.value5062);\n            foo(b.value5063);\n            foo(b.value5064);\n            foo(b.value5065);\n            foo(b.value5066);\n            foo(b.value5067);\n            foo(b.value5068);\n            foo(b.value5069);\n            foo(b.value5070);\n            foo(b.value5071);\n            foo(b.value5072);\n            foo(b.value5073);\n            foo(b.value5074);\n            foo(b.value5075);\n            foo(b.value5076);\n            foo(b.value5077);\n            foo(b.value5078);\n            foo(b.value5079);\n            foo(b.value5080);\n            foo(b.value5081);\n            foo(b.value5082);\n            foo(b.value5083);\n            foo(b.value5084);\n            foo(b.value5085);\n            foo(b.value5086);\n            foo(b.value5087);\n            foo(b.value5088);\n            foo(b.value5089);\n            foo(b.value5090);\n            foo(b.value5091);\n            foo(b.value5092);\n            foo(b.value5093);\n            foo(b.value5094);\n            foo(b.value5095);\n            foo(b.value5096);\n            foo(b.value5097);\n            foo(b.value5098);\n            foo(b.value5099);\n            foo(b.value5100);\n            foo(b.value5101);\n            foo(b.value5102);\n            foo(b.value5103);\n            foo(b.value5104);\n            foo(b.value5105);\n            foo(b.value5106);\n            foo(b.value5107);\n            foo(b.value5108);\n            foo(b.value5109);\n            foo(b.value5110);\n            foo(b.value5111);\n            foo(b.value5112);\n            foo(b.value5113);\n            foo(b.value5114);\n            foo(b.value5115);\n            foo(b.value5116);\n            foo(b.value5117);\n            foo(b.value5118);\n            foo(b.value5119);\n            foo(b.value5120);\n            foo(b.value5121);\n            foo(b.value5122);\n            foo(b.value5123);\n            foo(b.value5124);\n            foo(b.value5125);\n            foo(b.value5126);\n            foo(b.value5127);\n            foo(b.value5128);\n            foo(b.value5129);\n            foo(b.value5130);\n            foo(b.value5131);\n            foo(b.value5132);\n            foo(b.value5133);\n            foo(b.value5134);\n            foo(b.value5135);\n            foo(b.value5136);\n            foo(b.value5137);\n            foo(b.value5138);\n            foo(b.value5139);\n            foo(b.value5140);\n            foo(b.value5141);\n            foo(b.value5142);\n            foo(b.value5143);\n            foo(b.value5144);\n            foo(b.value5145);\n            foo(b.value5146);\n            foo(b.value5147);\n            foo(b.value5148);\n            foo(b.value5149);\n            foo(b.value5150);\n            foo(b.value5151);\n            foo(b.value5152);\n            foo(b.value5153);\n            foo(b.value5154);\n            foo(b.value5155);\n            foo(b.value5156);\n            foo(b.value5157);\n            foo(b.value5158);\n            foo(b.value5159);\n            foo(b.value5160);\n            foo(b.value5161);\n            foo(b.value5162);\n            foo(b.value5163);\n            foo(b.value5164);\n            foo(b.value5165);\n            foo(b.value5166);\n            foo(b.value5167);\n            foo(b.value5168);\n            foo(b.value5169);\n            foo(b.value5170);\n            foo(b.value5171);\n            foo(b.value5172);\n            foo(b.value5173);\n            foo(b.value5174);\n            foo(b.value5175);\n            foo(b.value5176);\n            foo(b.value5177);\n            foo(b.value5178);\n            foo(b.value5179);\n            foo(b.value5180);\n            foo(b.value5181);\n            foo(b.value5182);\n            foo(b.value5183);\n            foo(b.value5184);\n            foo(b.value5185);\n            foo(b.value5186);\n            foo(b.value5187);\n            foo(b.value5188);\n            foo(b.value5189);\n            foo(b.value5190);\n            foo(b.value5191);\n            foo(b.value5192);\n            foo(b.value5193);\n            foo(b.value5194);\n            foo(b.value5195);\n            foo(b.value5196);\n            foo(b.value5197);\n            foo(b.value5198);\n            foo(b.value5199);\n            foo(b.value5200);\n            foo(b.value5201);\n            foo(b.value5202);\n            foo(b.value5203);\n            foo(b.value5204);\n            foo(b.value5205);\n            foo(b.value5206);\n            foo(b.value5207);\n            foo(b.value5208);\n            foo(b.value5209);\n            foo(b.value5210);\n            foo(b.value5211);\n            foo(b.value5212);\n            foo(b.value5213);\n            foo(b.value5214);\n            foo(b.value5215);\n            foo(b.value5216);\n            foo(b.value5217);\n            foo(b.value5218);\n            foo(b.value5219);\n            foo(b.value5220);\n            foo(b.value5221);\n            foo(b.value5222);\n            foo(b.value5223);\n            foo(b.value5224);\n            foo(b.value5225);\n            foo(b.value5226);\n            foo(b.value5227);\n            foo(b.value5228);\n            foo(b.value5229);\n            foo(b.value5230);\n            foo(b.value5231);\n            foo(b.value5232);\n            foo(b.value5233);\n            foo(b.value5234);\n            foo(b.value5235);\n            foo(b.value5236);\n            foo(b.value5237);\n            foo(b.value5238);\n            foo(b.value5239);\n            foo(b.value5240);\n            foo(b.value5241);\n            foo(b.value5242);\n            foo(b.value5243);\n            foo(b.value5244);\n            foo(b.value5245);\n            foo(b.value5246);\n            foo(b.value5247);\n            foo(b.value5248);\n        }\n    }\n}\n\nListWrite.new(\"List Read\").run();\n"
  },
  {
    "path": "microbenchmarks/attribute_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nstruct ListWrite : Microbenchmark {\n    func test() {\n        for i in 0.to(50) {\n            val b = Box();\n            b.value0 = 0;\n            b.value1 = 1;\n            b.value2 = 2;\n            b.value3 = 3;\n            b.value4 = 4;\n            b.value5 = 5;\n            b.value6 = 6;\n            b.value7 = 7;\n            b.value8 = 8;\n            b.value9 = 9;\n            b.value10 = 10;\n            b.value11 = 11;\n            b.value12 = 12;\n            b.value13 = 13;\n            b.value14 = 14;\n            b.value15 = 15;\n            b.value16 = 16;\n            b.value17 = 17;\n            b.value18 = 18;\n            b.value19 = 19;\n            b.value20 = 20;\n            b.value21 = 21;\n            b.value22 = 22;\n            b.value23 = 23;\n            b.value24 = 24;\n            b.value25 = 25;\n            b.value26 = 26;\n            b.value27 = 27;\n            b.value28 = 28;\n            b.value29 = 29;\n            b.value30 = 30;\n            b.value31 = 31;\n            b.value32 = 32;\n            b.value33 = 33;\n            b.value34 = 34;\n            b.value35 = 35;\n            b.value36 = 36;\n            b.value37 = 37;\n            b.value38 = 38;\n            b.value39 = 39;\n            b.value40 = 40;\n            b.value41 = 41;\n            b.value42 = 42;\n            b.value43 = 43;\n            b.value44 = 44;\n            b.value45 = 45;\n            b.value46 = 46;\n            b.value47 = 47;\n            b.value48 = 48;\n            b.value49 = 49;\n            b.value50 = 50;\n            b.value51 = 51;\n            b.value52 = 52;\n            b.value53 = 53;\n            b.value54 = 54;\n            b.value55 = 55;\n            b.value56 = 56;\n            b.value57 = 57;\n            b.value58 = 58;\n            b.value59 = 59;\n            b.value60 = 60;\n            b.value61 = 61;\n            b.value62 = 62;\n            b.value63 = 63;\n            b.value64 = 64;\n            b.value65 = 65;\n            b.value66 = 66;\n            b.value67 = 67;\n            b.value68 = 68;\n            b.value69 = 69;\n            b.value70 = 70;\n            b.value71 = 71;\n            b.value72 = 72;\n            b.value73 = 73;\n            b.value74 = 74;\n            b.value75 = 75;\n            b.value76 = 76;\n            b.value77 = 77;\n            b.value78 = 78;\n            b.value79 = 79;\n            b.value80 = 80;\n            b.value81 = 81;\n            b.value82 = 82;\n            b.value83 = 83;\n            b.value84 = 84;\n            b.value85 = 85;\n            b.value86 = 86;\n            b.value87 = 87;\n            b.value88 = 88;\n            b.value89 = 89;\n            b.value90 = 90;\n            b.value91 = 91;\n            b.value92 = 92;\n            b.value93 = 93;\n            b.value94 = 94;\n            b.value95 = 95;\n            b.value96 = 96;\n            b.value97 = 97;\n            b.value98 = 98;\n            b.value99 = 99;\n            b.value100 = 100;\n            b.value101 = 101;\n            b.value102 = 102;\n            b.value103 = 103;\n            b.value104 = 104;\n            b.value105 = 105;\n            b.value106 = 106;\n            b.value107 = 107;\n            b.value108 = 108;\n            b.value109 = 109;\n            b.value110 = 110;\n            b.value111 = 111;\n            b.value112 = 112;\n            b.value113 = 113;\n            b.value114 = 114;\n            b.value115 = 115;\n            b.value116 = 116;\n            b.value117 = 117;\n            b.value118 = 118;\n            b.value119 = 119;\n            b.value120 = 120;\n            b.value121 = 121;\n            b.value122 = 122;\n            b.value123 = 123;\n            b.value124 = 124;\n            b.value125 = 125;\n            b.value126 = 126;\n            b.value127 = 127;\n            b.value128 = 128;\n            b.value129 = 129;\n            b.value130 = 130;\n            b.value131 = 131;\n            b.value132 = 132;\n            b.value133 = 133;\n            b.value134 = 134;\n            b.value135 = 135;\n            b.value136 = 136;\n            b.value137 = 137;\n            b.value138 = 138;\n            b.value139 = 139;\n            b.value140 = 140;\n            b.value141 = 141;\n            b.value142 = 142;\n            b.value143 = 143;\n            b.value144 = 144;\n            b.value145 = 145;\n            b.value146 = 146;\n            b.value147 = 147;\n            b.value148 = 148;\n            b.value149 = 149;\n            b.value150 = 150;\n            b.value151 = 151;\n            b.value152 = 152;\n            b.value153 = 153;\n            b.value154 = 154;\n            b.value155 = 155;\n            b.value156 = 156;\n            b.value157 = 157;\n            b.value158 = 158;\n            b.value159 = 159;\n            b.value160 = 160;\n            b.value161 = 161;\n            b.value162 = 162;\n            b.value163 = 163;\n            b.value164 = 164;\n            b.value165 = 165;\n            b.value166 = 166;\n            b.value167 = 167;\n            b.value168 = 168;\n            b.value169 = 169;\n            b.value170 = 170;\n            b.value171 = 171;\n            b.value172 = 172;\n            b.value173 = 173;\n            b.value174 = 174;\n            b.value175 = 175;\n            b.value176 = 176;\n            b.value177 = 177;\n            b.value178 = 178;\n            b.value179 = 179;\n            b.value180 = 180;\n            b.value181 = 181;\n            b.value182 = 182;\n            b.value183 = 183;\n            b.value184 = 184;\n            b.value185 = 185;\n            b.value186 = 186;\n            b.value187 = 187;\n            b.value188 = 188;\n            b.value189 = 189;\n            b.value190 = 190;\n            b.value191 = 191;\n            b.value192 = 192;\n            b.value193 = 193;\n            b.value194 = 194;\n            b.value195 = 195;\n            b.value196 = 196;\n            b.value197 = 197;\n            b.value198 = 198;\n            b.value199 = 199;\n            b.value200 = 200;\n            b.value201 = 201;\n            b.value202 = 202;\n            b.value203 = 203;\n            b.value204 = 204;\n            b.value205 = 205;\n            b.value206 = 206;\n            b.value207 = 207;\n            b.value208 = 208;\n            b.value209 = 209;\n            b.value210 = 210;\n            b.value211 = 211;\n            b.value212 = 212;\n            b.value213 = 213;\n            b.value214 = 214;\n            b.value215 = 215;\n            b.value216 = 216;\n            b.value217 = 217;\n            b.value218 = 218;\n            b.value219 = 219;\n            b.value220 = 220;\n            b.value221 = 221;\n            b.value222 = 222;\n            b.value223 = 223;\n            b.value224 = 224;\n            b.value225 = 225;\n            b.value226 = 226;\n            b.value227 = 227;\n            b.value228 = 228;\n            b.value229 = 229;\n            b.value230 = 230;\n            b.value231 = 231;\n            b.value232 = 232;\n            b.value233 = 233;\n            b.value234 = 234;\n            b.value235 = 235;\n            b.value236 = 236;\n            b.value237 = 237;\n            b.value238 = 238;\n            b.value239 = 239;\n            b.value240 = 240;\n            b.value241 = 241;\n            b.value242 = 242;\n            b.value243 = 243;\n            b.value244 = 244;\n            b.value245 = 245;\n            b.value246 = 246;\n            b.value247 = 247;\n            b.value248 = 248;\n            b.value249 = 249;\n            b.value250 = 250;\n            b.value251 = 251;\n            b.value252 = 252;\n            b.value253 = 253;\n            b.value254 = 254;\n            b.value255 = 255;\n            b.value256 = 256;\n            b.value257 = 257;\n            b.value258 = 258;\n            b.value259 = 259;\n            b.value260 = 260;\n            b.value261 = 261;\n            b.value262 = 262;\n            b.value263 = 263;\n            b.value264 = 264;\n            b.value265 = 265;\n            b.value266 = 266;\n            b.value267 = 267;\n            b.value268 = 268;\n            b.value269 = 269;\n            b.value270 = 270;\n            b.value271 = 271;\n            b.value272 = 272;\n            b.value273 = 273;\n            b.value274 = 274;\n            b.value275 = 275;\n            b.value276 = 276;\n            b.value277 = 277;\n            b.value278 = 278;\n            b.value279 = 279;\n            b.value280 = 280;\n            b.value281 = 281;\n            b.value282 = 282;\n            b.value283 = 283;\n            b.value284 = 284;\n            b.value285 = 285;\n            b.value286 = 286;\n            b.value287 = 287;\n            b.value288 = 288;\n            b.value289 = 289;\n            b.value290 = 290;\n            b.value291 = 291;\n            b.value292 = 292;\n            b.value293 = 293;\n            b.value294 = 294;\n            b.value295 = 295;\n            b.value296 = 296;\n            b.value297 = 297;\n            b.value298 = 298;\n            b.value299 = 299;\n            b.value300 = 300;\n            b.value301 = 301;\n            b.value302 = 302;\n            b.value303 = 303;\n            b.value304 = 304;\n            b.value305 = 305;\n            b.value306 = 306;\n            b.value307 = 307;\n            b.value308 = 308;\n            b.value309 = 309;\n            b.value310 = 310;\n            b.value311 = 311;\n            b.value312 = 312;\n            b.value313 = 313;\n            b.value314 = 314;\n            b.value315 = 315;\n            b.value316 = 316;\n            b.value317 = 317;\n            b.value318 = 318;\n            b.value319 = 319;\n            b.value320 = 320;\n            b.value321 = 321;\n            b.value322 = 322;\n            b.value323 = 323;\n            b.value324 = 324;\n            b.value325 = 325;\n            b.value326 = 326;\n            b.value327 = 327;\n            b.value328 = 328;\n            b.value329 = 329;\n            b.value330 = 330;\n            b.value331 = 331;\n            b.value332 = 332;\n            b.value333 = 333;\n            b.value334 = 334;\n            b.value335 = 335;\n            b.value336 = 336;\n            b.value337 = 337;\n            b.value338 = 338;\n            b.value339 = 339;\n            b.value340 = 340;\n            b.value341 = 341;\n            b.value342 = 342;\n            b.value343 = 343;\n            b.value344 = 344;\n            b.value345 = 345;\n            b.value346 = 346;\n            b.value347 = 347;\n            b.value348 = 348;\n            b.value349 = 349;\n            b.value350 = 350;\n            b.value351 = 351;\n            b.value352 = 352;\n            b.value353 = 353;\n            b.value354 = 354;\n            b.value355 = 355;\n            b.value356 = 356;\n            b.value357 = 357;\n            b.value358 = 358;\n            b.value359 = 359;\n            b.value360 = 360;\n            b.value361 = 361;\n            b.value362 = 362;\n            b.value363 = 363;\n            b.value364 = 364;\n            b.value365 = 365;\n            b.value366 = 366;\n            b.value367 = 367;\n            b.value368 = 368;\n            b.value369 = 369;\n            b.value370 = 370;\n            b.value371 = 371;\n            b.value372 = 372;\n            b.value373 = 373;\n            b.value374 = 374;\n            b.value375 = 375;\n            b.value376 = 376;\n            b.value377 = 377;\n            b.value378 = 378;\n            b.value379 = 379;\n            b.value380 = 380;\n            b.value381 = 381;\n            b.value382 = 382;\n            b.value383 = 383;\n            b.value384 = 384;\n            b.value385 = 385;\n            b.value386 = 386;\n            b.value387 = 387;\n            b.value388 = 388;\n            b.value389 = 389;\n            b.value390 = 390;\n            b.value391 = 391;\n            b.value392 = 392;\n            b.value393 = 393;\n            b.value394 = 394;\n            b.value395 = 395;\n            b.value396 = 396;\n            b.value397 = 397;\n            b.value398 = 398;\n            b.value399 = 399;\n            b.value400 = 400;\n            b.value401 = 401;\n            b.value402 = 402;\n            b.value403 = 403;\n            b.value404 = 404;\n            b.value405 = 405;\n            b.value406 = 406;\n            b.value407 = 407;\n            b.value408 = 408;\n            b.value409 = 409;\n            b.value410 = 410;\n            b.value411 = 411;\n            b.value412 = 412;\n            b.value413 = 413;\n            b.value414 = 414;\n            b.value415 = 415;\n            b.value416 = 416;\n            b.value417 = 417;\n            b.value418 = 418;\n            b.value419 = 419;\n            b.value420 = 420;\n            b.value421 = 421;\n            b.value422 = 422;\n            b.value423 = 423;\n            b.value424 = 424;\n            b.value425 = 425;\n            b.value426 = 426;\n            b.value427 = 427;\n            b.value428 = 428;\n            b.value429 = 429;\n            b.value430 = 430;\n            b.value431 = 431;\n            b.value432 = 432;\n            b.value433 = 433;\n            b.value434 = 434;\n            b.value435 = 435;\n            b.value436 = 436;\n            b.value437 = 437;\n            b.value438 = 438;\n            b.value439 = 439;\n            b.value440 = 440;\n            b.value441 = 441;\n            b.value442 = 442;\n            b.value443 = 443;\n            b.value444 = 444;\n            b.value445 = 445;\n            b.value446 = 446;\n            b.value447 = 447;\n            b.value448 = 448;\n            b.value449 = 449;\n            b.value450 = 450;\n            b.value451 = 451;\n            b.value452 = 452;\n            b.value453 = 453;\n            b.value454 = 454;\n            b.value455 = 455;\n            b.value456 = 456;\n            b.value457 = 457;\n            b.value458 = 458;\n            b.value459 = 459;\n            b.value460 = 460;\n            b.value461 = 461;\n            b.value462 = 462;\n            b.value463 = 463;\n            b.value464 = 464;\n            b.value465 = 465;\n            b.value466 = 466;\n            b.value467 = 467;\n            b.value468 = 468;\n            b.value469 = 469;\n            b.value470 = 470;\n            b.value471 = 471;\n            b.value472 = 472;\n            b.value473 = 473;\n            b.value474 = 474;\n            b.value475 = 475;\n            b.value476 = 476;\n            b.value477 = 477;\n            b.value478 = 478;\n            b.value479 = 479;\n            b.value480 = 480;\n            b.value481 = 481;\n            b.value482 = 482;\n            b.value483 = 483;\n            b.value484 = 484;\n            b.value485 = 485;\n            b.value486 = 486;\n            b.value487 = 487;\n            b.value488 = 488;\n            b.value489 = 489;\n            b.value490 = 490;\n            b.value491 = 491;\n            b.value492 = 492;\n            b.value493 = 493;\n            b.value494 = 494;\n            b.value495 = 495;\n            b.value496 = 496;\n            b.value497 = 497;\n            b.value498 = 498;\n            b.value499 = 499;\n            b.value500 = 500;\n            b.value501 = 501;\n            b.value502 = 502;\n            b.value503 = 503;\n            b.value504 = 504;\n            b.value505 = 505;\n            b.value506 = 506;\n            b.value507 = 507;\n            b.value508 = 508;\n            b.value509 = 509;\n            b.value510 = 510;\n            b.value511 = 511;\n            b.value512 = 512;\n            b.value513 = 513;\n            b.value514 = 514;\n            b.value515 = 515;\n            b.value516 = 516;\n            b.value517 = 517;\n            b.value518 = 518;\n            b.value519 = 519;\n            b.value520 = 520;\n            b.value521 = 521;\n            b.value522 = 522;\n            b.value523 = 523;\n            b.value524 = 524;\n            b.value525 = 525;\n            b.value526 = 526;\n            b.value527 = 527;\n            b.value528 = 528;\n            b.value529 = 529;\n            b.value530 = 530;\n            b.value531 = 531;\n            b.value532 = 532;\n            b.value533 = 533;\n            b.value534 = 534;\n            b.value535 = 535;\n            b.value536 = 536;\n            b.value537 = 537;\n            b.value538 = 538;\n            b.value539 = 539;\n            b.value540 = 540;\n            b.value541 = 541;\n            b.value542 = 542;\n            b.value543 = 543;\n            b.value544 = 544;\n            b.value545 = 545;\n            b.value546 = 546;\n            b.value547 = 547;\n            b.value548 = 548;\n            b.value549 = 549;\n            b.value550 = 550;\n            b.value551 = 551;\n            b.value552 = 552;\n            b.value553 = 553;\n            b.value554 = 554;\n            b.value555 = 555;\n            b.value556 = 556;\n            b.value557 = 557;\n            b.value558 = 558;\n            b.value559 = 559;\n            b.value560 = 560;\n            b.value561 = 561;\n            b.value562 = 562;\n            b.value563 = 563;\n            b.value564 = 564;\n            b.value565 = 565;\n            b.value566 = 566;\n            b.value567 = 567;\n            b.value568 = 568;\n            b.value569 = 569;\n            b.value570 = 570;\n            b.value571 = 571;\n            b.value572 = 572;\n            b.value573 = 573;\n            b.value574 = 574;\n            b.value575 = 575;\n            b.value576 = 576;\n            b.value577 = 577;\n            b.value578 = 578;\n            b.value579 = 579;\n            b.value580 = 580;\n            b.value581 = 581;\n            b.value582 = 582;\n            b.value583 = 583;\n            b.value584 = 584;\n            b.value585 = 585;\n            b.value586 = 586;\n            b.value587 = 587;\n            b.value588 = 588;\n            b.value589 = 589;\n            b.value590 = 590;\n            b.value591 = 591;\n            b.value592 = 592;\n            b.value593 = 593;\n            b.value594 = 594;\n            b.value595 = 595;\n            b.value596 = 596;\n            b.value597 = 597;\n            b.value598 = 598;\n            b.value599 = 599;\n            b.value600 = 600;\n            b.value601 = 601;\n            b.value602 = 602;\n            b.value603 = 603;\n            b.value604 = 604;\n            b.value605 = 605;\n            b.value606 = 606;\n            b.value607 = 607;\n            b.value608 = 608;\n            b.value609 = 609;\n            b.value610 = 610;\n            b.value611 = 611;\n            b.value612 = 612;\n            b.value613 = 613;\n            b.value614 = 614;\n            b.value615 = 615;\n            b.value616 = 616;\n            b.value617 = 617;\n            b.value618 = 618;\n            b.value619 = 619;\n            b.value620 = 620;\n            b.value621 = 621;\n            b.value622 = 622;\n            b.value623 = 623;\n            b.value624 = 624;\n            b.value625 = 625;\n            b.value626 = 626;\n            b.value627 = 627;\n            b.value628 = 628;\n            b.value629 = 629;\n            b.value630 = 630;\n            b.value631 = 631;\n            b.value632 = 632;\n            b.value633 = 633;\n            b.value634 = 634;\n            b.value635 = 635;\n            b.value636 = 636;\n            b.value637 = 637;\n            b.value638 = 638;\n            b.value639 = 639;\n            b.value640 = 640;\n            b.value641 = 641;\n            b.value642 = 642;\n            b.value643 = 643;\n            b.value644 = 644;\n            b.value645 = 645;\n            b.value646 = 646;\n            b.value647 = 647;\n            b.value648 = 648;\n            b.value649 = 649;\n            b.value650 = 650;\n            b.value651 = 651;\n            b.value652 = 652;\n            b.value653 = 653;\n            b.value654 = 654;\n            b.value655 = 655;\n            b.value656 = 656;\n            b.value657 = 657;\n            b.value658 = 658;\n            b.value659 = 659;\n            b.value660 = 660;\n            b.value661 = 661;\n            b.value662 = 662;\n            b.value663 = 663;\n            b.value664 = 664;\n            b.value665 = 665;\n            b.value666 = 666;\n            b.value667 = 667;\n            b.value668 = 668;\n            b.value669 = 669;\n            b.value670 = 670;\n            b.value671 = 671;\n            b.value672 = 672;\n            b.value673 = 673;\n            b.value674 = 674;\n            b.value675 = 675;\n            b.value676 = 676;\n            b.value677 = 677;\n            b.value678 = 678;\n            b.value679 = 679;\n            b.value680 = 680;\n            b.value681 = 681;\n            b.value682 = 682;\n            b.value683 = 683;\n            b.value684 = 684;\n            b.value685 = 685;\n            b.value686 = 686;\n            b.value687 = 687;\n            b.value688 = 688;\n            b.value689 = 689;\n            b.value690 = 690;\n            b.value691 = 691;\n            b.value692 = 692;\n            b.value693 = 693;\n            b.value694 = 694;\n            b.value695 = 695;\n            b.value696 = 696;\n            b.value697 = 697;\n            b.value698 = 698;\n            b.value699 = 699;\n            b.value700 = 700;\n            b.value701 = 701;\n            b.value702 = 702;\n            b.value703 = 703;\n            b.value704 = 704;\n            b.value705 = 705;\n            b.value706 = 706;\n            b.value707 = 707;\n            b.value708 = 708;\n            b.value709 = 709;\n            b.value710 = 710;\n            b.value711 = 711;\n            b.value712 = 712;\n            b.value713 = 713;\n            b.value714 = 714;\n            b.value715 = 715;\n            b.value716 = 716;\n            b.value717 = 717;\n            b.value718 = 718;\n            b.value719 = 719;\n            b.value720 = 720;\n            b.value721 = 721;\n            b.value722 = 722;\n            b.value723 = 723;\n            b.value724 = 724;\n            b.value725 = 725;\n            b.value726 = 726;\n            b.value727 = 727;\n            b.value728 = 728;\n            b.value729 = 729;\n            b.value730 = 730;\n            b.value731 = 731;\n            b.value732 = 732;\n            b.value733 = 733;\n            b.value734 = 734;\n            b.value735 = 735;\n            b.value736 = 736;\n            b.value737 = 737;\n            b.value738 = 738;\n            b.value739 = 739;\n            b.value740 = 740;\n            b.value741 = 741;\n            b.value742 = 742;\n            b.value743 = 743;\n            b.value744 = 744;\n            b.value745 = 745;\n            b.value746 = 746;\n            b.value747 = 747;\n            b.value748 = 748;\n            b.value749 = 749;\n            b.value750 = 750;\n            b.value751 = 751;\n            b.value752 = 752;\n            b.value753 = 753;\n            b.value754 = 754;\n            b.value755 = 755;\n            b.value756 = 756;\n            b.value757 = 757;\n            b.value758 = 758;\n            b.value759 = 759;\n            b.value760 = 760;\n            b.value761 = 761;\n            b.value762 = 762;\n            b.value763 = 763;\n            b.value764 = 764;\n            b.value765 = 765;\n            b.value766 = 766;\n            b.value767 = 767;\n            b.value768 = 768;\n            b.value769 = 769;\n            b.value770 = 770;\n            b.value771 = 771;\n            b.value772 = 772;\n            b.value773 = 773;\n            b.value774 = 774;\n            b.value775 = 775;\n            b.value776 = 776;\n            b.value777 = 777;\n            b.value778 = 778;\n            b.value779 = 779;\n            b.value780 = 780;\n            b.value781 = 781;\n            b.value782 = 782;\n            b.value783 = 783;\n            b.value784 = 784;\n            b.value785 = 785;\n            b.value786 = 786;\n            b.value787 = 787;\n            b.value788 = 788;\n            b.value789 = 789;\n            b.value790 = 790;\n            b.value791 = 791;\n            b.value792 = 792;\n            b.value793 = 793;\n            b.value794 = 794;\n            b.value795 = 795;\n            b.value796 = 796;\n            b.value797 = 797;\n            b.value798 = 798;\n            b.value799 = 799;\n            b.value800 = 800;\n            b.value801 = 801;\n            b.value802 = 802;\n            b.value803 = 803;\n            b.value804 = 804;\n            b.value805 = 805;\n            b.value806 = 806;\n            b.value807 = 807;\n            b.value808 = 808;\n            b.value809 = 809;\n            b.value810 = 810;\n            b.value811 = 811;\n            b.value812 = 812;\n            b.value813 = 813;\n            b.value814 = 814;\n            b.value815 = 815;\n            b.value816 = 816;\n            b.value817 = 817;\n            b.value818 = 818;\n            b.value819 = 819;\n            b.value820 = 820;\n            b.value821 = 821;\n            b.value822 = 822;\n            b.value823 = 823;\n            b.value824 = 824;\n            b.value825 = 825;\n            b.value826 = 826;\n            b.value827 = 827;\n            b.value828 = 828;\n            b.value829 = 829;\n            b.value830 = 830;\n            b.value831 = 831;\n            b.value832 = 832;\n            b.value833 = 833;\n            b.value834 = 834;\n            b.value835 = 835;\n            b.value836 = 836;\n            b.value837 = 837;\n            b.value838 = 838;\n            b.value839 = 839;\n            b.value840 = 840;\n            b.value841 = 841;\n            b.value842 = 842;\n            b.value843 = 843;\n            b.value844 = 844;\n            b.value845 = 845;\n            b.value846 = 846;\n            b.value847 = 847;\n            b.value848 = 848;\n            b.value849 = 849;\n            b.value850 = 850;\n            b.value851 = 851;\n            b.value852 = 852;\n            b.value853 = 853;\n            b.value854 = 854;\n            b.value855 = 855;\n            b.value856 = 856;\n            b.value857 = 857;\n            b.value858 = 858;\n            b.value859 = 859;\n            b.value860 = 860;\n            b.value861 = 861;\n            b.value862 = 862;\n            b.value863 = 863;\n            b.value864 = 864;\n            b.value865 = 865;\n            b.value866 = 866;\n            b.value867 = 867;\n            b.value868 = 868;\n            b.value869 = 869;\n            b.value870 = 870;\n            b.value871 = 871;\n            b.value872 = 872;\n            b.value873 = 873;\n            b.value874 = 874;\n            b.value875 = 875;\n            b.value876 = 876;\n            b.value877 = 877;\n            b.value878 = 878;\n            b.value879 = 879;\n            b.value880 = 880;\n            b.value881 = 881;\n            b.value882 = 882;\n            b.value883 = 883;\n            b.value884 = 884;\n            b.value885 = 885;\n            b.value886 = 886;\n            b.value887 = 887;\n            b.value888 = 888;\n            b.value889 = 889;\n            b.value890 = 890;\n            b.value891 = 891;\n            b.value892 = 892;\n            b.value893 = 893;\n            b.value894 = 894;\n            b.value895 = 895;\n            b.value896 = 896;\n            b.value897 = 897;\n            b.value898 = 898;\n            b.value899 = 899;\n            b.value900 = 900;\n            b.value901 = 901;\n            b.value902 = 902;\n            b.value903 = 903;\n            b.value904 = 904;\n            b.value905 = 905;\n            b.value906 = 906;\n            b.value907 = 907;\n            b.value908 = 908;\n            b.value909 = 909;\n            b.value910 = 910;\n            b.value911 = 911;\n            b.value912 = 912;\n            b.value913 = 913;\n            b.value914 = 914;\n            b.value915 = 915;\n            b.value916 = 916;\n            b.value917 = 917;\n            b.value918 = 918;\n            b.value919 = 919;\n            b.value920 = 920;\n            b.value921 = 921;\n            b.value922 = 922;\n            b.value923 = 923;\n            b.value924 = 924;\n            b.value925 = 925;\n            b.value926 = 926;\n            b.value927 = 927;\n            b.value928 = 928;\n            b.value929 = 929;\n            b.value930 = 930;\n            b.value931 = 931;\n            b.value932 = 932;\n            b.value933 = 933;\n            b.value934 = 934;\n            b.value935 = 935;\n            b.value936 = 936;\n            b.value937 = 937;\n            b.value938 = 938;\n            b.value939 = 939;\n            b.value940 = 940;\n            b.value941 = 941;\n            b.value942 = 942;\n            b.value943 = 943;\n            b.value944 = 944;\n            b.value945 = 945;\n            b.value946 = 946;\n            b.value947 = 947;\n            b.value948 = 948;\n            b.value949 = 949;\n            b.value950 = 950;\n            b.value951 = 951;\n            b.value952 = 952;\n            b.value953 = 953;\n            b.value954 = 954;\n            b.value955 = 955;\n            b.value956 = 956;\n            b.value957 = 957;\n            b.value958 = 958;\n            b.value959 = 959;\n            b.value960 = 960;\n            b.value961 = 961;\n            b.value962 = 962;\n            b.value963 = 963;\n            b.value964 = 964;\n            b.value965 = 965;\n            b.value966 = 966;\n            b.value967 = 967;\n            b.value968 = 968;\n            b.value969 = 969;\n            b.value970 = 970;\n            b.value971 = 971;\n            b.value972 = 972;\n            b.value973 = 973;\n            b.value974 = 974;\n            b.value975 = 975;\n            b.value976 = 976;\n            b.value977 = 977;\n            b.value978 = 978;\n            b.value979 = 979;\n            b.value980 = 980;\n            b.value981 = 981;\n            b.value982 = 982;\n            b.value983 = 983;\n            b.value984 = 984;\n            b.value985 = 985;\n            b.value986 = 986;\n            b.value987 = 987;\n            b.value988 = 988;\n            b.value989 = 989;\n            b.value990 = 990;\n            b.value991 = 991;\n            b.value992 = 992;\n            b.value993 = 993;\n            b.value994 = 994;\n            b.value995 = 995;\n            b.value996 = 996;\n            b.value997 = 997;\n            b.value998 = 998;\n            b.value999 = 999;\n            b.value1000 = 1000;\n            b.value1001 = 1001;\n            b.value1002 = 1002;\n            b.value1003 = 1003;\n            b.value1004 = 1004;\n            b.value1005 = 1005;\n            b.value1006 = 1006;\n            b.value1007 = 1007;\n            b.value1008 = 1008;\n            b.value1009 = 1009;\n            b.value1010 = 1010;\n            b.value1011 = 1011;\n            b.value1012 = 1012;\n            b.value1013 = 1013;\n            b.value1014 = 1014;\n            b.value1015 = 1015;\n            b.value1016 = 1016;\n            b.value1017 = 1017;\n            b.value1018 = 1018;\n            b.value1019 = 1019;\n            b.value1020 = 1020;\n            b.value1021 = 1021;\n            b.value1022 = 1022;\n            b.value1023 = 1023;\n            b.value1024 = 1024;\n            b.value1025 = 1025;\n            b.value1026 = 1026;\n            b.value1027 = 1027;\n            b.value1028 = 1028;\n            b.value1029 = 1029;\n            b.value1030 = 1030;\n            b.value1031 = 1031;\n            b.value1032 = 1032;\n            b.value1033 = 1033;\n            b.value1034 = 1034;\n            b.value1035 = 1035;\n            b.value1036 = 1036;\n            b.value1037 = 1037;\n            b.value1038 = 1038;\n            b.value1039 = 1039;\n            b.value1040 = 1040;\n            b.value1041 = 1041;\n            b.value1042 = 1042;\n            b.value1043 = 1043;\n            b.value1044 = 1044;\n            b.value1045 = 1045;\n            b.value1046 = 1046;\n            b.value1047 = 1047;\n            b.value1048 = 1048;\n            b.value1049 = 1049;\n            b.value1050 = 1050;\n            b.value1051 = 1051;\n            b.value1052 = 1052;\n            b.value1053 = 1053;\n            b.value1054 = 1054;\n            b.value1055 = 1055;\n            b.value1056 = 1056;\n            b.value1057 = 1057;\n            b.value1058 = 1058;\n            b.value1059 = 1059;\n            b.value1060 = 1060;\n            b.value1061 = 1061;\n            b.value1062 = 1062;\n            b.value1063 = 1063;\n            b.value1064 = 1064;\n            b.value1065 = 1065;\n            b.value1066 = 1066;\n            b.value1067 = 1067;\n            b.value1068 = 1068;\n            b.value1069 = 1069;\n            b.value1070 = 1070;\n            b.value1071 = 1071;\n            b.value1072 = 1072;\n            b.value1073 = 1073;\n            b.value1074 = 1074;\n            b.value1075 = 1075;\n            b.value1076 = 1076;\n            b.value1077 = 1077;\n            b.value1078 = 1078;\n            b.value1079 = 1079;\n            b.value1080 = 1080;\n            b.value1081 = 1081;\n            b.value1082 = 1082;\n            b.value1083 = 1083;\n            b.value1084 = 1084;\n            b.value1085 = 1085;\n            b.value1086 = 1086;\n            b.value1087 = 1087;\n            b.value1088 = 1088;\n            b.value1089 = 1089;\n            b.value1090 = 1090;\n            b.value1091 = 1091;\n            b.value1092 = 1092;\n            b.value1093 = 1093;\n            b.value1094 = 1094;\n            b.value1095 = 1095;\n            b.value1096 = 1096;\n            b.value1097 = 1097;\n            b.value1098 = 1098;\n            b.value1099 = 1099;\n            b.value1100 = 1100;\n            b.value1101 = 1101;\n            b.value1102 = 1102;\n            b.value1103 = 1103;\n            b.value1104 = 1104;\n            b.value1105 = 1105;\n            b.value1106 = 1106;\n            b.value1107 = 1107;\n            b.value1108 = 1108;\n            b.value1109 = 1109;\n            b.value1110 = 1110;\n            b.value1111 = 1111;\n            b.value1112 = 1112;\n            b.value1113 = 1113;\n            b.value1114 = 1114;\n            b.value1115 = 1115;\n            b.value1116 = 1116;\n            b.value1117 = 1117;\n            b.value1118 = 1118;\n            b.value1119 = 1119;\n            b.value1120 = 1120;\n            b.value1121 = 1121;\n            b.value1122 = 1122;\n            b.value1123 = 1123;\n            b.value1124 = 1124;\n            b.value1125 = 1125;\n            b.value1126 = 1126;\n            b.value1127 = 1127;\n            b.value1128 = 1128;\n            b.value1129 = 1129;\n            b.value1130 = 1130;\n            b.value1131 = 1131;\n            b.value1132 = 1132;\n            b.value1133 = 1133;\n            b.value1134 = 1134;\n            b.value1135 = 1135;\n            b.value1136 = 1136;\n            b.value1137 = 1137;\n            b.value1138 = 1138;\n            b.value1139 = 1139;\n            b.value1140 = 1140;\n            b.value1141 = 1141;\n            b.value1142 = 1142;\n            b.value1143 = 1143;\n            b.value1144 = 1144;\n            b.value1145 = 1145;\n            b.value1146 = 1146;\n            b.value1147 = 1147;\n            b.value1148 = 1148;\n            b.value1149 = 1149;\n            b.value1150 = 1150;\n            b.value1151 = 1151;\n            b.value1152 = 1152;\n            b.value1153 = 1153;\n            b.value1154 = 1154;\n            b.value1155 = 1155;\n            b.value1156 = 1156;\n            b.value1157 = 1157;\n            b.value1158 = 1158;\n            b.value1159 = 1159;\n            b.value1160 = 1160;\n            b.value1161 = 1161;\n            b.value1162 = 1162;\n            b.value1163 = 1163;\n            b.value1164 = 1164;\n            b.value1165 = 1165;\n            b.value1166 = 1166;\n            b.value1167 = 1167;\n            b.value1168 = 1168;\n            b.value1169 = 1169;\n            b.value1170 = 1170;\n            b.value1171 = 1171;\n            b.value1172 = 1172;\n            b.value1173 = 1173;\n            b.value1174 = 1174;\n            b.value1175 = 1175;\n            b.value1176 = 1176;\n            b.value1177 = 1177;\n            b.value1178 = 1178;\n            b.value1179 = 1179;\n            b.value1180 = 1180;\n            b.value1181 = 1181;\n            b.value1182 = 1182;\n            b.value1183 = 1183;\n            b.value1184 = 1184;\n            b.value1185 = 1185;\n            b.value1186 = 1186;\n            b.value1187 = 1187;\n            b.value1188 = 1188;\n            b.value1189 = 1189;\n            b.value1190 = 1190;\n            b.value1191 = 1191;\n            b.value1192 = 1192;\n            b.value1193 = 1193;\n            b.value1194 = 1194;\n            b.value1195 = 1195;\n            b.value1196 = 1196;\n            b.value1197 = 1197;\n            b.value1198 = 1198;\n            b.value1199 = 1199;\n            b.value1200 = 1200;\n            b.value1201 = 1201;\n            b.value1202 = 1202;\n            b.value1203 = 1203;\n            b.value1204 = 1204;\n            b.value1205 = 1205;\n            b.value1206 = 1206;\n            b.value1207 = 1207;\n            b.value1208 = 1208;\n            b.value1209 = 1209;\n            b.value1210 = 1210;\n            b.value1211 = 1211;\n            b.value1212 = 1212;\n            b.value1213 = 1213;\n            b.value1214 = 1214;\n            b.value1215 = 1215;\n            b.value1216 = 1216;\n            b.value1217 = 1217;\n            b.value1218 = 1218;\n            b.value1219 = 1219;\n            b.value1220 = 1220;\n            b.value1221 = 1221;\n            b.value1222 = 1222;\n            b.value1223 = 1223;\n            b.value1224 = 1224;\n            b.value1225 = 1225;\n            b.value1226 = 1226;\n            b.value1227 = 1227;\n            b.value1228 = 1228;\n            b.value1229 = 1229;\n            b.value1230 = 1230;\n            b.value1231 = 1231;\n            b.value1232 = 1232;\n            b.value1233 = 1233;\n            b.value1234 = 1234;\n            b.value1235 = 1235;\n            b.value1236 = 1236;\n            b.value1237 = 1237;\n            b.value1238 = 1238;\n            b.value1239 = 1239;\n            b.value1240 = 1240;\n            b.value1241 = 1241;\n            b.value1242 = 1242;\n            b.value1243 = 1243;\n            b.value1244 = 1244;\n            b.value1245 = 1245;\n            b.value1246 = 1246;\n            b.value1247 = 1247;\n            b.value1248 = 1248;\n            b.value1249 = 1249;\n            b.value1250 = 1250;\n            b.value1251 = 1251;\n            b.value1252 = 1252;\n            b.value1253 = 1253;\n            b.value1254 = 1254;\n            b.value1255 = 1255;\n            b.value1256 = 1256;\n            b.value1257 = 1257;\n            b.value1258 = 1258;\n            b.value1259 = 1259;\n            b.value1260 = 1260;\n            b.value1261 = 1261;\n            b.value1262 = 1262;\n            b.value1263 = 1263;\n            b.value1264 = 1264;\n            b.value1265 = 1265;\n            b.value1266 = 1266;\n            b.value1267 = 1267;\n            b.value1268 = 1268;\n            b.value1269 = 1269;\n            b.value1270 = 1270;\n            b.value1271 = 1271;\n            b.value1272 = 1272;\n            b.value1273 = 1273;\n            b.value1274 = 1274;\n            b.value1275 = 1275;\n            b.value1276 = 1276;\n            b.value1277 = 1277;\n            b.value1278 = 1278;\n            b.value1279 = 1279;\n            b.value1280 = 1280;\n            b.value1281 = 1281;\n            b.value1282 = 1282;\n            b.value1283 = 1283;\n            b.value1284 = 1284;\n            b.value1285 = 1285;\n            b.value1286 = 1286;\n            b.value1287 = 1287;\n            b.value1288 = 1288;\n            b.value1289 = 1289;\n            b.value1290 = 1290;\n            b.value1291 = 1291;\n            b.value1292 = 1292;\n            b.value1293 = 1293;\n            b.value1294 = 1294;\n            b.value1295 = 1295;\n            b.value1296 = 1296;\n            b.value1297 = 1297;\n            b.value1298 = 1298;\n            b.value1299 = 1299;\n            b.value1300 = 1300;\n            b.value1301 = 1301;\n            b.value1302 = 1302;\n            b.value1303 = 1303;\n            b.value1304 = 1304;\n            b.value1305 = 1305;\n            b.value1306 = 1306;\n            b.value1307 = 1307;\n            b.value1308 = 1308;\n            b.value1309 = 1309;\n            b.value1310 = 1310;\n            b.value1311 = 1311;\n            b.value1312 = 1312;\n            b.value1313 = 1313;\n            b.value1314 = 1314;\n            b.value1315 = 1315;\n            b.value1316 = 1316;\n            b.value1317 = 1317;\n            b.value1318 = 1318;\n            b.value1319 = 1319;\n            b.value1320 = 1320;\n            b.value1321 = 1321;\n            b.value1322 = 1322;\n            b.value1323 = 1323;\n            b.value1324 = 1324;\n            b.value1325 = 1325;\n            b.value1326 = 1326;\n            b.value1327 = 1327;\n            b.value1328 = 1328;\n            b.value1329 = 1329;\n            b.value1330 = 1330;\n            b.value1331 = 1331;\n            b.value1332 = 1332;\n            b.value1333 = 1333;\n            b.value1334 = 1334;\n            b.value1335 = 1335;\n            b.value1336 = 1336;\n            b.value1337 = 1337;\n            b.value1338 = 1338;\n            b.value1339 = 1339;\n            b.value1340 = 1340;\n            b.value1341 = 1341;\n            b.value1342 = 1342;\n            b.value1343 = 1343;\n            b.value1344 = 1344;\n            b.value1345 = 1345;\n            b.value1346 = 1346;\n            b.value1347 = 1347;\n            b.value1348 = 1348;\n            b.value1349 = 1349;\n            b.value1350 = 1350;\n            b.value1351 = 1351;\n            b.value1352 = 1352;\n            b.value1353 = 1353;\n            b.value1354 = 1354;\n            b.value1355 = 1355;\n            b.value1356 = 1356;\n            b.value1357 = 1357;\n            b.value1358 = 1358;\n            b.value1359 = 1359;\n            b.value1360 = 1360;\n            b.value1361 = 1361;\n            b.value1362 = 1362;\n            b.value1363 = 1363;\n            b.value1364 = 1364;\n            b.value1365 = 1365;\n            b.value1366 = 1366;\n            b.value1367 = 1367;\n            b.value1368 = 1368;\n            b.value1369 = 1369;\n            b.value1370 = 1370;\n            b.value1371 = 1371;\n            b.value1372 = 1372;\n            b.value1373 = 1373;\n            b.value1374 = 1374;\n            b.value1375 = 1375;\n            b.value1376 = 1376;\n            b.value1377 = 1377;\n            b.value1378 = 1378;\n            b.value1379 = 1379;\n            b.value1380 = 1380;\n            b.value1381 = 1381;\n            b.value1382 = 1382;\n            b.value1383 = 1383;\n            b.value1384 = 1384;\n            b.value1385 = 1385;\n            b.value1386 = 1386;\n            b.value1387 = 1387;\n            b.value1388 = 1388;\n            b.value1389 = 1389;\n            b.value1390 = 1390;\n            b.value1391 = 1391;\n            b.value1392 = 1392;\n            b.value1393 = 1393;\n            b.value1394 = 1394;\n            b.value1395 = 1395;\n            b.value1396 = 1396;\n            b.value1397 = 1397;\n            b.value1398 = 1398;\n            b.value1399 = 1399;\n            b.value1400 = 1400;\n            b.value1401 = 1401;\n            b.value1402 = 1402;\n            b.value1403 = 1403;\n            b.value1404 = 1404;\n            b.value1405 = 1405;\n            b.value1406 = 1406;\n            b.value1407 = 1407;\n            b.value1408 = 1408;\n            b.value1409 = 1409;\n            b.value1410 = 1410;\n            b.value1411 = 1411;\n            b.value1412 = 1412;\n            b.value1413 = 1413;\n            b.value1414 = 1414;\n            b.value1415 = 1415;\n            b.value1416 = 1416;\n            b.value1417 = 1417;\n            b.value1418 = 1418;\n            b.value1419 = 1419;\n            b.value1420 = 1420;\n            b.value1421 = 1421;\n            b.value1422 = 1422;\n            b.value1423 = 1423;\n            b.value1424 = 1424;\n            b.value1425 = 1425;\n            b.value1426 = 1426;\n            b.value1427 = 1427;\n            b.value1428 = 1428;\n            b.value1429 = 1429;\n            b.value1430 = 1430;\n            b.value1431 = 1431;\n            b.value1432 = 1432;\n            b.value1433 = 1433;\n            b.value1434 = 1434;\n            b.value1435 = 1435;\n            b.value1436 = 1436;\n            b.value1437 = 1437;\n            b.value1438 = 1438;\n            b.value1439 = 1439;\n            b.value1440 = 1440;\n            b.value1441 = 1441;\n            b.value1442 = 1442;\n            b.value1443 = 1443;\n            b.value1444 = 1444;\n            b.value1445 = 1445;\n            b.value1446 = 1446;\n            b.value1447 = 1447;\n            b.value1448 = 1448;\n            b.value1449 = 1449;\n            b.value1450 = 1450;\n            b.value1451 = 1451;\n            b.value1452 = 1452;\n            b.value1453 = 1453;\n            b.value1454 = 1454;\n            b.value1455 = 1455;\n            b.value1456 = 1456;\n            b.value1457 = 1457;\n            b.value1458 = 1458;\n            b.value1459 = 1459;\n            b.value1460 = 1460;\n            b.value1461 = 1461;\n            b.value1462 = 1462;\n            b.value1463 = 1463;\n            b.value1464 = 1464;\n            b.value1465 = 1465;\n            b.value1466 = 1466;\n            b.value1467 = 1467;\n            b.value1468 = 1468;\n            b.value1469 = 1469;\n            b.value1470 = 1470;\n            b.value1471 = 1471;\n            b.value1472 = 1472;\n            b.value1473 = 1473;\n            b.value1474 = 1474;\n            b.value1475 = 1475;\n            b.value1476 = 1476;\n            b.value1477 = 1477;\n            b.value1478 = 1478;\n            b.value1479 = 1479;\n            b.value1480 = 1480;\n            b.value1481 = 1481;\n            b.value1482 = 1482;\n            b.value1483 = 1483;\n            b.value1484 = 1484;\n            b.value1485 = 1485;\n            b.value1486 = 1486;\n            b.value1487 = 1487;\n            b.value1488 = 1488;\n            b.value1489 = 1489;\n            b.value1490 = 1490;\n            b.value1491 = 1491;\n            b.value1492 = 1492;\n            b.value1493 = 1493;\n            b.value1494 = 1494;\n            b.value1495 = 1495;\n            b.value1496 = 1496;\n            b.value1497 = 1497;\n            b.value1498 = 1498;\n            b.value1499 = 1499;\n            b.value1500 = 1500;\n            b.value1501 = 1501;\n            b.value1502 = 1502;\n            b.value1503 = 1503;\n            b.value1504 = 1504;\n            b.value1505 = 1505;\n            b.value1506 = 1506;\n            b.value1507 = 1507;\n            b.value1508 = 1508;\n            b.value1509 = 1509;\n            b.value1510 = 1510;\n            b.value1511 = 1511;\n            b.value1512 = 1512;\n            b.value1513 = 1513;\n            b.value1514 = 1514;\n            b.value1515 = 1515;\n            b.value1516 = 1516;\n            b.value1517 = 1517;\n            b.value1518 = 1518;\n            b.value1519 = 1519;\n            b.value1520 = 1520;\n            b.value1521 = 1521;\n            b.value1522 = 1522;\n            b.value1523 = 1523;\n            b.value1524 = 1524;\n            b.value1525 = 1525;\n            b.value1526 = 1526;\n            b.value1527 = 1527;\n            b.value1528 = 1528;\n            b.value1529 = 1529;\n            b.value1530 = 1530;\n            b.value1531 = 1531;\n            b.value1532 = 1532;\n            b.value1533 = 1533;\n            b.value1534 = 1534;\n            b.value1535 = 1535;\n            b.value1536 = 1536;\n            b.value1537 = 1537;\n            b.value1538 = 1538;\n            b.value1539 = 1539;\n            b.value1540 = 1540;\n            b.value1541 = 1541;\n            b.value1542 = 1542;\n            b.value1543 = 1543;\n            b.value1544 = 1544;\n            b.value1545 = 1545;\n            b.value1546 = 1546;\n            b.value1547 = 1547;\n            b.value1548 = 1548;\n            b.value1549 = 1549;\n            b.value1550 = 1550;\n            b.value1551 = 1551;\n            b.value1552 = 1552;\n            b.value1553 = 1553;\n            b.value1554 = 1554;\n            b.value1555 = 1555;\n            b.value1556 = 1556;\n            b.value1557 = 1557;\n            b.value1558 = 1558;\n            b.value1559 = 1559;\n            b.value1560 = 1560;\n            b.value1561 = 1561;\n            b.value1562 = 1562;\n            b.value1563 = 1563;\n            b.value1564 = 1564;\n            b.value1565 = 1565;\n            b.value1566 = 1566;\n            b.value1567 = 1567;\n            b.value1568 = 1568;\n            b.value1569 = 1569;\n            b.value1570 = 1570;\n            b.value1571 = 1571;\n            b.value1572 = 1572;\n            b.value1573 = 1573;\n            b.value1574 = 1574;\n            b.value1575 = 1575;\n            b.value1576 = 1576;\n            b.value1577 = 1577;\n            b.value1578 = 1578;\n            b.value1579 = 1579;\n            b.value1580 = 1580;\n            b.value1581 = 1581;\n            b.value1582 = 1582;\n            b.value1583 = 1583;\n            b.value1584 = 1584;\n            b.value1585 = 1585;\n            b.value1586 = 1586;\n            b.value1587 = 1587;\n            b.value1588 = 1588;\n            b.value1589 = 1589;\n            b.value1590 = 1590;\n            b.value1591 = 1591;\n            b.value1592 = 1592;\n            b.value1593 = 1593;\n            b.value1594 = 1594;\n            b.value1595 = 1595;\n            b.value1596 = 1596;\n            b.value1597 = 1597;\n            b.value1598 = 1598;\n            b.value1599 = 1599;\n            b.value1600 = 1600;\n            b.value1601 = 1601;\n            b.value1602 = 1602;\n            b.value1603 = 1603;\n            b.value1604 = 1604;\n            b.value1605 = 1605;\n            b.value1606 = 1606;\n            b.value1607 = 1607;\n            b.value1608 = 1608;\n            b.value1609 = 1609;\n            b.value1610 = 1610;\n            b.value1611 = 1611;\n            b.value1612 = 1612;\n            b.value1613 = 1613;\n            b.value1614 = 1614;\n            b.value1615 = 1615;\n            b.value1616 = 1616;\n            b.value1617 = 1617;\n            b.value1618 = 1618;\n            b.value1619 = 1619;\n            b.value1620 = 1620;\n            b.value1621 = 1621;\n            b.value1622 = 1622;\n            b.value1623 = 1623;\n            b.value1624 = 1624;\n            b.value1625 = 1625;\n            b.value1626 = 1626;\n            b.value1627 = 1627;\n            b.value1628 = 1628;\n            b.value1629 = 1629;\n            b.value1630 = 1630;\n            b.value1631 = 1631;\n            b.value1632 = 1632;\n            b.value1633 = 1633;\n            b.value1634 = 1634;\n            b.value1635 = 1635;\n            b.value1636 = 1636;\n            b.value1637 = 1637;\n            b.value1638 = 1638;\n            b.value1639 = 1639;\n            b.value1640 = 1640;\n            b.value1641 = 1641;\n            b.value1642 = 1642;\n            b.value1643 = 1643;\n            b.value1644 = 1644;\n            b.value1645 = 1645;\n            b.value1646 = 1646;\n            b.value1647 = 1647;\n            b.value1648 = 1648;\n            b.value1649 = 1649;\n            b.value1650 = 1650;\n            b.value1651 = 1651;\n            b.value1652 = 1652;\n            b.value1653 = 1653;\n            b.value1654 = 1654;\n            b.value1655 = 1655;\n            b.value1656 = 1656;\n            b.value1657 = 1657;\n            b.value1658 = 1658;\n            b.value1659 = 1659;\n            b.value1660 = 1660;\n            b.value1661 = 1661;\n            b.value1662 = 1662;\n            b.value1663 = 1663;\n            b.value1664 = 1664;\n            b.value1665 = 1665;\n            b.value1666 = 1666;\n            b.value1667 = 1667;\n            b.value1668 = 1668;\n            b.value1669 = 1669;\n            b.value1670 = 1670;\n            b.value1671 = 1671;\n            b.value1672 = 1672;\n            b.value1673 = 1673;\n            b.value1674 = 1674;\n            b.value1675 = 1675;\n            b.value1676 = 1676;\n            b.value1677 = 1677;\n            b.value1678 = 1678;\n            b.value1679 = 1679;\n            b.value1680 = 1680;\n            b.value1681 = 1681;\n            b.value1682 = 1682;\n            b.value1683 = 1683;\n            b.value1684 = 1684;\n            b.value1685 = 1685;\n            b.value1686 = 1686;\n            b.value1687 = 1687;\n            b.value1688 = 1688;\n            b.value1689 = 1689;\n            b.value1690 = 1690;\n            b.value1691 = 1691;\n            b.value1692 = 1692;\n            b.value1693 = 1693;\n            b.value1694 = 1694;\n            b.value1695 = 1695;\n            b.value1696 = 1696;\n            b.value1697 = 1697;\n            b.value1698 = 1698;\n            b.value1699 = 1699;\n            b.value1700 = 1700;\n            b.value1701 = 1701;\n            b.value1702 = 1702;\n            b.value1703 = 1703;\n            b.value1704 = 1704;\n            b.value1705 = 1705;\n            b.value1706 = 1706;\n            b.value1707 = 1707;\n            b.value1708 = 1708;\n            b.value1709 = 1709;\n            b.value1710 = 1710;\n            b.value1711 = 1711;\n            b.value1712 = 1712;\n            b.value1713 = 1713;\n            b.value1714 = 1714;\n            b.value1715 = 1715;\n            b.value1716 = 1716;\n            b.value1717 = 1717;\n            b.value1718 = 1718;\n            b.value1719 = 1719;\n            b.value1720 = 1720;\n            b.value1721 = 1721;\n            b.value1722 = 1722;\n            b.value1723 = 1723;\n            b.value1724 = 1724;\n            b.value1725 = 1725;\n            b.value1726 = 1726;\n            b.value1727 = 1727;\n            b.value1728 = 1728;\n            b.value1729 = 1729;\n            b.value1730 = 1730;\n            b.value1731 = 1731;\n            b.value1732 = 1732;\n            b.value1733 = 1733;\n            b.value1734 = 1734;\n            b.value1735 = 1735;\n            b.value1736 = 1736;\n            b.value1737 = 1737;\n            b.value1738 = 1738;\n            b.value1739 = 1739;\n            b.value1740 = 1740;\n            b.value1741 = 1741;\n            b.value1742 = 1742;\n            b.value1743 = 1743;\n            b.value1744 = 1744;\n            b.value1745 = 1745;\n            b.value1746 = 1746;\n            b.value1747 = 1747;\n            b.value1748 = 1748;\n            b.value1749 = 1749;\n            b.value1750 = 1750;\n            b.value1751 = 1751;\n            b.value1752 = 1752;\n            b.value1753 = 1753;\n            b.value1754 = 1754;\n            b.value1755 = 1755;\n            b.value1756 = 1756;\n            b.value1757 = 1757;\n            b.value1758 = 1758;\n            b.value1759 = 1759;\n            b.value1760 = 1760;\n            b.value1761 = 1761;\n            b.value1762 = 1762;\n            b.value1763 = 1763;\n            b.value1764 = 1764;\n            b.value1765 = 1765;\n            b.value1766 = 1766;\n            b.value1767 = 1767;\n            b.value1768 = 1768;\n            b.value1769 = 1769;\n            b.value1770 = 1770;\n            b.value1771 = 1771;\n            b.value1772 = 1772;\n            b.value1773 = 1773;\n            b.value1774 = 1774;\n            b.value1775 = 1775;\n            b.value1776 = 1776;\n            b.value1777 = 1777;\n            b.value1778 = 1778;\n            b.value1779 = 1779;\n            b.value1780 = 1780;\n            b.value1781 = 1781;\n            b.value1782 = 1782;\n            b.value1783 = 1783;\n            b.value1784 = 1784;\n            b.value1785 = 1785;\n            b.value1786 = 1786;\n            b.value1787 = 1787;\n            b.value1788 = 1788;\n            b.value1789 = 1789;\n            b.value1790 = 1790;\n            b.value1791 = 1791;\n            b.value1792 = 1792;\n            b.value1793 = 1793;\n            b.value1794 = 1794;\n            b.value1795 = 1795;\n            b.value1796 = 1796;\n            b.value1797 = 1797;\n            b.value1798 = 1798;\n            b.value1799 = 1799;\n            b.value1800 = 1800;\n            b.value1801 = 1801;\n            b.value1802 = 1802;\n            b.value1803 = 1803;\n            b.value1804 = 1804;\n            b.value1805 = 1805;\n            b.value1806 = 1806;\n            b.value1807 = 1807;\n            b.value1808 = 1808;\n            b.value1809 = 1809;\n            b.value1810 = 1810;\n            b.value1811 = 1811;\n            b.value1812 = 1812;\n            b.value1813 = 1813;\n            b.value1814 = 1814;\n            b.value1815 = 1815;\n            b.value1816 = 1816;\n            b.value1817 = 1817;\n            b.value1818 = 1818;\n            b.value1819 = 1819;\n            b.value1820 = 1820;\n            b.value1821 = 1821;\n            b.value1822 = 1822;\n            b.value1823 = 1823;\n            b.value1824 = 1824;\n            b.value1825 = 1825;\n            b.value1826 = 1826;\n            b.value1827 = 1827;\n            b.value1828 = 1828;\n            b.value1829 = 1829;\n            b.value1830 = 1830;\n            b.value1831 = 1831;\n            b.value1832 = 1832;\n            b.value1833 = 1833;\n            b.value1834 = 1834;\n            b.value1835 = 1835;\n            b.value1836 = 1836;\n            b.value1837 = 1837;\n            b.value1838 = 1838;\n            b.value1839 = 1839;\n            b.value1840 = 1840;\n            b.value1841 = 1841;\n            b.value1842 = 1842;\n            b.value1843 = 1843;\n            b.value1844 = 1844;\n            b.value1845 = 1845;\n            b.value1846 = 1846;\n            b.value1847 = 1847;\n            b.value1848 = 1848;\n            b.value1849 = 1849;\n            b.value1850 = 1850;\n            b.value1851 = 1851;\n            b.value1852 = 1852;\n            b.value1853 = 1853;\n            b.value1854 = 1854;\n            b.value1855 = 1855;\n            b.value1856 = 1856;\n            b.value1857 = 1857;\n            b.value1858 = 1858;\n            b.value1859 = 1859;\n            b.value1860 = 1860;\n            b.value1861 = 1861;\n            b.value1862 = 1862;\n            b.value1863 = 1863;\n            b.value1864 = 1864;\n            b.value1865 = 1865;\n            b.value1866 = 1866;\n            b.value1867 = 1867;\n            b.value1868 = 1868;\n            b.value1869 = 1869;\n            b.value1870 = 1870;\n            b.value1871 = 1871;\n            b.value1872 = 1872;\n            b.value1873 = 1873;\n            b.value1874 = 1874;\n            b.value1875 = 1875;\n            b.value1876 = 1876;\n            b.value1877 = 1877;\n            b.value1878 = 1878;\n            b.value1879 = 1879;\n            b.value1880 = 1880;\n            b.value1881 = 1881;\n            b.value1882 = 1882;\n            b.value1883 = 1883;\n            b.value1884 = 1884;\n            b.value1885 = 1885;\n            b.value1886 = 1886;\n            b.value1887 = 1887;\n            b.value1888 = 1888;\n            b.value1889 = 1889;\n            b.value1890 = 1890;\n            b.value1891 = 1891;\n            b.value1892 = 1892;\n            b.value1893 = 1893;\n            b.value1894 = 1894;\n            b.value1895 = 1895;\n            b.value1896 = 1896;\n            b.value1897 = 1897;\n            b.value1898 = 1898;\n            b.value1899 = 1899;\n            b.value1900 = 1900;\n            b.value1901 = 1901;\n            b.value1902 = 1902;\n            b.value1903 = 1903;\n            b.value1904 = 1904;\n            b.value1905 = 1905;\n            b.value1906 = 1906;\n            b.value1907 = 1907;\n            b.value1908 = 1908;\n            b.value1909 = 1909;\n            b.value1910 = 1910;\n            b.value1911 = 1911;\n            b.value1912 = 1912;\n            b.value1913 = 1913;\n            b.value1914 = 1914;\n            b.value1915 = 1915;\n            b.value1916 = 1916;\n            b.value1917 = 1917;\n            b.value1918 = 1918;\n            b.value1919 = 1919;\n            b.value1920 = 1920;\n            b.value1921 = 1921;\n            b.value1922 = 1922;\n            b.value1923 = 1923;\n            b.value1924 = 1924;\n            b.value1925 = 1925;\n            b.value1926 = 1926;\n            b.value1927 = 1927;\n            b.value1928 = 1928;\n            b.value1929 = 1929;\n            b.value1930 = 1930;\n            b.value1931 = 1931;\n            b.value1932 = 1932;\n            b.value1933 = 1933;\n            b.value1934 = 1934;\n            b.value1935 = 1935;\n            b.value1936 = 1936;\n            b.value1937 = 1937;\n            b.value1938 = 1938;\n            b.value1939 = 1939;\n            b.value1940 = 1940;\n            b.value1941 = 1941;\n            b.value1942 = 1942;\n            b.value1943 = 1943;\n            b.value1944 = 1944;\n            b.value1945 = 1945;\n            b.value1946 = 1946;\n            b.value1947 = 1947;\n            b.value1948 = 1948;\n            b.value1949 = 1949;\n            b.value1950 = 1950;\n            b.value1951 = 1951;\n            b.value1952 = 1952;\n            b.value1953 = 1953;\n            b.value1954 = 1954;\n            b.value1955 = 1955;\n            b.value1956 = 1956;\n            b.value1957 = 1957;\n            b.value1958 = 1958;\n            b.value1959 = 1959;\n            b.value1960 = 1960;\n            b.value1961 = 1961;\n            b.value1962 = 1962;\n            b.value1963 = 1963;\n            b.value1964 = 1964;\n            b.value1965 = 1965;\n            b.value1966 = 1966;\n            b.value1967 = 1967;\n            b.value1968 = 1968;\n            b.value1969 = 1969;\n            b.value1970 = 1970;\n            b.value1971 = 1971;\n            b.value1972 = 1972;\n            b.value1973 = 1973;\n            b.value1974 = 1974;\n            b.value1975 = 1975;\n            b.value1976 = 1976;\n            b.value1977 = 1977;\n            b.value1978 = 1978;\n            b.value1979 = 1979;\n            b.value1980 = 1980;\n            b.value1981 = 1981;\n            b.value1982 = 1982;\n            b.value1983 = 1983;\n            b.value1984 = 1984;\n            b.value1985 = 1985;\n            b.value1986 = 1986;\n            b.value1987 = 1987;\n            b.value1988 = 1988;\n            b.value1989 = 1989;\n            b.value1990 = 1990;\n            b.value1991 = 1991;\n            b.value1992 = 1992;\n            b.value1993 = 1993;\n            b.value1994 = 1994;\n            b.value1995 = 1995;\n            b.value1996 = 1996;\n            b.value1997 = 1997;\n            b.value1998 = 1998;\n            b.value1999 = 1999;\n            b.value2000 = 2000;\n            b.value2001 = 2001;\n            b.value2002 = 2002;\n            b.value2003 = 2003;\n            b.value2004 = 2004;\n            b.value2005 = 2005;\n            b.value2006 = 2006;\n            b.value2007 = 2007;\n            b.value2008 = 2008;\n            b.value2009 = 2009;\n            b.value2010 = 2010;\n            b.value2011 = 2011;\n            b.value2012 = 2012;\n            b.value2013 = 2013;\n            b.value2014 = 2014;\n            b.value2015 = 2015;\n            b.value2016 = 2016;\n            b.value2017 = 2017;\n            b.value2018 = 2018;\n            b.value2019 = 2019;\n            b.value2020 = 2020;\n            b.value2021 = 2021;\n            b.value2022 = 2022;\n            b.value2023 = 2023;\n            b.value2024 = 2024;\n            b.value2025 = 2025;\n            b.value2026 = 2026;\n            b.value2027 = 2027;\n            b.value2028 = 2028;\n            b.value2029 = 2029;\n            b.value2030 = 2030;\n            b.value2031 = 2031;\n            b.value2032 = 2032;\n            b.value2033 = 2033;\n            b.value2034 = 2034;\n            b.value2035 = 2035;\n            b.value2036 = 2036;\n            b.value2037 = 2037;\n            b.value2038 = 2038;\n            b.value2039 = 2039;\n            b.value2040 = 2040;\n            b.value2041 = 2041;\n            b.value2042 = 2042;\n            b.value2043 = 2043;\n            b.value2044 = 2044;\n            b.value2045 = 2045;\n            b.value2046 = 2046;\n            b.value2047 = 2047;\n            b.value2048 = 2048;\n            b.value2049 = 2049;\n            b.value2050 = 2050;\n            b.value2051 = 2051;\n            b.value2052 = 2052;\n            b.value2053 = 2053;\n            b.value2054 = 2054;\n            b.value2055 = 2055;\n            b.value2056 = 2056;\n            b.value2057 = 2057;\n            b.value2058 = 2058;\n            b.value2059 = 2059;\n            b.value2060 = 2060;\n            b.value2061 = 2061;\n            b.value2062 = 2062;\n            b.value2063 = 2063;\n            b.value2064 = 2064;\n            b.value2065 = 2065;\n            b.value2066 = 2066;\n            b.value2067 = 2067;\n            b.value2068 = 2068;\n            b.value2069 = 2069;\n            b.value2070 = 2070;\n            b.value2071 = 2071;\n            b.value2072 = 2072;\n            b.value2073 = 2073;\n            b.value2074 = 2074;\n            b.value2075 = 2075;\n            b.value2076 = 2076;\n            b.value2077 = 2077;\n            b.value2078 = 2078;\n            b.value2079 = 2079;\n            b.value2080 = 2080;\n            b.value2081 = 2081;\n            b.value2082 = 2082;\n            b.value2083 = 2083;\n            b.value2084 = 2084;\n            b.value2085 = 2085;\n            b.value2086 = 2086;\n            b.value2087 = 2087;\n            b.value2088 = 2088;\n            b.value2089 = 2089;\n            b.value2090 = 2090;\n            b.value2091 = 2091;\n            b.value2092 = 2092;\n            b.value2093 = 2093;\n            b.value2094 = 2094;\n            b.value2095 = 2095;\n            b.value2096 = 2096;\n            b.value2097 = 2097;\n            b.value2098 = 2098;\n            b.value2099 = 2099;\n            b.value2100 = 2100;\n            b.value2101 = 2101;\n            b.value2102 = 2102;\n            b.value2103 = 2103;\n            b.value2104 = 2104;\n            b.value2105 = 2105;\n            b.value2106 = 2106;\n            b.value2107 = 2107;\n            b.value2108 = 2108;\n            b.value2109 = 2109;\n            b.value2110 = 2110;\n            b.value2111 = 2111;\n            b.value2112 = 2112;\n            b.value2113 = 2113;\n            b.value2114 = 2114;\n            b.value2115 = 2115;\n            b.value2116 = 2116;\n            b.value2117 = 2117;\n            b.value2118 = 2118;\n            b.value2119 = 2119;\n            b.value2120 = 2120;\n            b.value2121 = 2121;\n            b.value2122 = 2122;\n            b.value2123 = 2123;\n            b.value2124 = 2124;\n            b.value2125 = 2125;\n            b.value2126 = 2126;\n            b.value2127 = 2127;\n            b.value2128 = 2128;\n            b.value2129 = 2129;\n            b.value2130 = 2130;\n            b.value2131 = 2131;\n            b.value2132 = 2132;\n            b.value2133 = 2133;\n            b.value2134 = 2134;\n            b.value2135 = 2135;\n            b.value2136 = 2136;\n            b.value2137 = 2137;\n            b.value2138 = 2138;\n            b.value2139 = 2139;\n            b.value2140 = 2140;\n            b.value2141 = 2141;\n            b.value2142 = 2142;\n            b.value2143 = 2143;\n            b.value2144 = 2144;\n            b.value2145 = 2145;\n            b.value2146 = 2146;\n            b.value2147 = 2147;\n            b.value2148 = 2148;\n            b.value2149 = 2149;\n            b.value2150 = 2150;\n            b.value2151 = 2151;\n            b.value2152 = 2152;\n            b.value2153 = 2153;\n            b.value2154 = 2154;\n            b.value2155 = 2155;\n            b.value2156 = 2156;\n            b.value2157 = 2157;\n            b.value2158 = 2158;\n            b.value2159 = 2159;\n            b.value2160 = 2160;\n            b.value2161 = 2161;\n            b.value2162 = 2162;\n            b.value2163 = 2163;\n            b.value2164 = 2164;\n            b.value2165 = 2165;\n            b.value2166 = 2166;\n            b.value2167 = 2167;\n            b.value2168 = 2168;\n            b.value2169 = 2169;\n            b.value2170 = 2170;\n            b.value2171 = 2171;\n            b.value2172 = 2172;\n            b.value2173 = 2173;\n            b.value2174 = 2174;\n            b.value2175 = 2175;\n            b.value2176 = 2176;\n            b.value2177 = 2177;\n            b.value2178 = 2178;\n            b.value2179 = 2179;\n            b.value2180 = 2180;\n            b.value2181 = 2181;\n            b.value2182 = 2182;\n            b.value2183 = 2183;\n            b.value2184 = 2184;\n            b.value2185 = 2185;\n            b.value2186 = 2186;\n            b.value2187 = 2187;\n            b.value2188 = 2188;\n            b.value2189 = 2189;\n            b.value2190 = 2190;\n            b.value2191 = 2191;\n            b.value2192 = 2192;\n            b.value2193 = 2193;\n            b.value2194 = 2194;\n            b.value2195 = 2195;\n            b.value2196 = 2196;\n            b.value2197 = 2197;\n            b.value2198 = 2198;\n            b.value2199 = 2199;\n            b.value2200 = 2200;\n            b.value2201 = 2201;\n            b.value2202 = 2202;\n            b.value2203 = 2203;\n            b.value2204 = 2204;\n            b.value2205 = 2205;\n            b.value2206 = 2206;\n            b.value2207 = 2207;\n            b.value2208 = 2208;\n            b.value2209 = 2209;\n            b.value2210 = 2210;\n            b.value2211 = 2211;\n            b.value2212 = 2212;\n            b.value2213 = 2213;\n            b.value2214 = 2214;\n            b.value2215 = 2215;\n            b.value2216 = 2216;\n            b.value2217 = 2217;\n            b.value2218 = 2218;\n            b.value2219 = 2219;\n            b.value2220 = 2220;\n            b.value2221 = 2221;\n            b.value2222 = 2222;\n            b.value2223 = 2223;\n            b.value2224 = 2224;\n            b.value2225 = 2225;\n            b.value2226 = 2226;\n            b.value2227 = 2227;\n            b.value2228 = 2228;\n            b.value2229 = 2229;\n            b.value2230 = 2230;\n            b.value2231 = 2231;\n            b.value2232 = 2232;\n            b.value2233 = 2233;\n            b.value2234 = 2234;\n            b.value2235 = 2235;\n            b.value2236 = 2236;\n            b.value2237 = 2237;\n            b.value2238 = 2238;\n            b.value2239 = 2239;\n            b.value2240 = 2240;\n            b.value2241 = 2241;\n            b.value2242 = 2242;\n            b.value2243 = 2243;\n            b.value2244 = 2244;\n            b.value2245 = 2245;\n            b.value2246 = 2246;\n            b.value2247 = 2247;\n            b.value2248 = 2248;\n            b.value2249 = 2249;\n            b.value2250 = 2250;\n            b.value2251 = 2251;\n            b.value2252 = 2252;\n            b.value2253 = 2253;\n            b.value2254 = 2254;\n            b.value2255 = 2255;\n            b.value2256 = 2256;\n            b.value2257 = 2257;\n            b.value2258 = 2258;\n            b.value2259 = 2259;\n            b.value2260 = 2260;\n            b.value2261 = 2261;\n            b.value2262 = 2262;\n            b.value2263 = 2263;\n            b.value2264 = 2264;\n            b.value2265 = 2265;\n            b.value2266 = 2266;\n            b.value2267 = 2267;\n            b.value2268 = 2268;\n            b.value2269 = 2269;\n            b.value2270 = 2270;\n            b.value2271 = 2271;\n            b.value2272 = 2272;\n            b.value2273 = 2273;\n            b.value2274 = 2274;\n            b.value2275 = 2275;\n            b.value2276 = 2276;\n            b.value2277 = 2277;\n            b.value2278 = 2278;\n            b.value2279 = 2279;\n            b.value2280 = 2280;\n            b.value2281 = 2281;\n            b.value2282 = 2282;\n            b.value2283 = 2283;\n            b.value2284 = 2284;\n            b.value2285 = 2285;\n            b.value2286 = 2286;\n            b.value2287 = 2287;\n            b.value2288 = 2288;\n            b.value2289 = 2289;\n            b.value2290 = 2290;\n            b.value2291 = 2291;\n            b.value2292 = 2292;\n            b.value2293 = 2293;\n            b.value2294 = 2294;\n            b.value2295 = 2295;\n            b.value2296 = 2296;\n            b.value2297 = 2297;\n            b.value2298 = 2298;\n            b.value2299 = 2299;\n            b.value2300 = 2300;\n            b.value2301 = 2301;\n            b.value2302 = 2302;\n            b.value2303 = 2303;\n            b.value2304 = 2304;\n            b.value2305 = 2305;\n            b.value2306 = 2306;\n            b.value2307 = 2307;\n            b.value2308 = 2308;\n            b.value2309 = 2309;\n            b.value2310 = 2310;\n            b.value2311 = 2311;\n            b.value2312 = 2312;\n            b.value2313 = 2313;\n            b.value2314 = 2314;\n            b.value2315 = 2315;\n            b.value2316 = 2316;\n            b.value2317 = 2317;\n            b.value2318 = 2318;\n            b.value2319 = 2319;\n            b.value2320 = 2320;\n            b.value2321 = 2321;\n            b.value2322 = 2322;\n            b.value2323 = 2323;\n            b.value2324 = 2324;\n            b.value2325 = 2325;\n            b.value2326 = 2326;\n            b.value2327 = 2327;\n            b.value2328 = 2328;\n            b.value2329 = 2329;\n            b.value2330 = 2330;\n            b.value2331 = 2331;\n            b.value2332 = 2332;\n            b.value2333 = 2333;\n            b.value2334 = 2334;\n            b.value2335 = 2335;\n            b.value2336 = 2336;\n            b.value2337 = 2337;\n            b.value2338 = 2338;\n            b.value2339 = 2339;\n            b.value2340 = 2340;\n            b.value2341 = 2341;\n            b.value2342 = 2342;\n            b.value2343 = 2343;\n            b.value2344 = 2344;\n            b.value2345 = 2345;\n            b.value2346 = 2346;\n            b.value2347 = 2347;\n            b.value2348 = 2348;\n            b.value2349 = 2349;\n            b.value2350 = 2350;\n            b.value2351 = 2351;\n            b.value2352 = 2352;\n            b.value2353 = 2353;\n            b.value2354 = 2354;\n            b.value2355 = 2355;\n            b.value2356 = 2356;\n            b.value2357 = 2357;\n            b.value2358 = 2358;\n            b.value2359 = 2359;\n            b.value2360 = 2360;\n            b.value2361 = 2361;\n            b.value2362 = 2362;\n            b.value2363 = 2363;\n            b.value2364 = 2364;\n            b.value2365 = 2365;\n            b.value2366 = 2366;\n            b.value2367 = 2367;\n            b.value2368 = 2368;\n            b.value2369 = 2369;\n            b.value2370 = 2370;\n            b.value2371 = 2371;\n            b.value2372 = 2372;\n            b.value2373 = 2373;\n            b.value2374 = 2374;\n            b.value2375 = 2375;\n            b.value2376 = 2376;\n            b.value2377 = 2377;\n            b.value2378 = 2378;\n            b.value2379 = 2379;\n            b.value2380 = 2380;\n            b.value2381 = 2381;\n            b.value2382 = 2382;\n            b.value2383 = 2383;\n            b.value2384 = 2384;\n            b.value2385 = 2385;\n            b.value2386 = 2386;\n            b.value2387 = 2387;\n            b.value2388 = 2388;\n            b.value2389 = 2389;\n            b.value2390 = 2390;\n            b.value2391 = 2391;\n            b.value2392 = 2392;\n            b.value2393 = 2393;\n            b.value2394 = 2394;\n            b.value2395 = 2395;\n            b.value2396 = 2396;\n            b.value2397 = 2397;\n            b.value2398 = 2398;\n            b.value2399 = 2399;\n            b.value2400 = 2400;\n            b.value2401 = 2401;\n            b.value2402 = 2402;\n            b.value2403 = 2403;\n            b.value2404 = 2404;\n            b.value2405 = 2405;\n            b.value2406 = 2406;\n            b.value2407 = 2407;\n            b.value2408 = 2408;\n            b.value2409 = 2409;\n            b.value2410 = 2410;\n            b.value2411 = 2411;\n            b.value2412 = 2412;\n            b.value2413 = 2413;\n            b.value2414 = 2414;\n            b.value2415 = 2415;\n            b.value2416 = 2416;\n            b.value2417 = 2417;\n            b.value2418 = 2418;\n            b.value2419 = 2419;\n            b.value2420 = 2420;\n            b.value2421 = 2421;\n            b.value2422 = 2422;\n            b.value2423 = 2423;\n            b.value2424 = 2424;\n            b.value2425 = 2425;\n            b.value2426 = 2426;\n            b.value2427 = 2427;\n            b.value2428 = 2428;\n            b.value2429 = 2429;\n            b.value2430 = 2430;\n            b.value2431 = 2431;\n            b.value2432 = 2432;\n            b.value2433 = 2433;\n            b.value2434 = 2434;\n            b.value2435 = 2435;\n            b.value2436 = 2436;\n            b.value2437 = 2437;\n            b.value2438 = 2438;\n            b.value2439 = 2439;\n            b.value2440 = 2440;\n            b.value2441 = 2441;\n            b.value2442 = 2442;\n            b.value2443 = 2443;\n            b.value2444 = 2444;\n            b.value2445 = 2445;\n            b.value2446 = 2446;\n            b.value2447 = 2447;\n            b.value2448 = 2448;\n            b.value2449 = 2449;\n            b.value2450 = 2450;\n            b.value2451 = 2451;\n            b.value2452 = 2452;\n            b.value2453 = 2453;\n            b.value2454 = 2454;\n            b.value2455 = 2455;\n            b.value2456 = 2456;\n            b.value2457 = 2457;\n            b.value2458 = 2458;\n            b.value2459 = 2459;\n            b.value2460 = 2460;\n            b.value2461 = 2461;\n            b.value2462 = 2462;\n            b.value2463 = 2463;\n            b.value2464 = 2464;\n            b.value2465 = 2465;\n            b.value2466 = 2466;\n            b.value2467 = 2467;\n            b.value2468 = 2468;\n            b.value2469 = 2469;\n            b.value2470 = 2470;\n            b.value2471 = 2471;\n            b.value2472 = 2472;\n            b.value2473 = 2473;\n            b.value2474 = 2474;\n            b.value2475 = 2475;\n            b.value2476 = 2476;\n            b.value2477 = 2477;\n            b.value2478 = 2478;\n            b.value2479 = 2479;\n            b.value2480 = 2480;\n            b.value2481 = 2481;\n            b.value2482 = 2482;\n            b.value2483 = 2483;\n            b.value2484 = 2484;\n            b.value2485 = 2485;\n            b.value2486 = 2486;\n            b.value2487 = 2487;\n            b.value2488 = 2488;\n            b.value2489 = 2489;\n            b.value2490 = 2490;\n            b.value2491 = 2491;\n            b.value2492 = 2492;\n            b.value2493 = 2493;\n            b.value2494 = 2494;\n            b.value2495 = 2495;\n            b.value2496 = 2496;\n            b.value2497 = 2497;\n            b.value2498 = 2498;\n            b.value2499 = 2499;\n            b.value2500 = 2500;\n            b.value2501 = 2501;\n            b.value2502 = 2502;\n            b.value2503 = 2503;\n            b.value2504 = 2504;\n            b.value2505 = 2505;\n            b.value2506 = 2506;\n            b.value2507 = 2507;\n            b.value2508 = 2508;\n            b.value2509 = 2509;\n            b.value2510 = 2510;\n            b.value2511 = 2511;\n            b.value2512 = 2512;\n            b.value2513 = 2513;\n            b.value2514 = 2514;\n            b.value2515 = 2515;\n            b.value2516 = 2516;\n            b.value2517 = 2517;\n            b.value2518 = 2518;\n            b.value2519 = 2519;\n            b.value2520 = 2520;\n            b.value2521 = 2521;\n            b.value2522 = 2522;\n            b.value2523 = 2523;\n            b.value2524 = 2524;\n            b.value2525 = 2525;\n            b.value2526 = 2526;\n            b.value2527 = 2527;\n            b.value2528 = 2528;\n            b.value2529 = 2529;\n            b.value2530 = 2530;\n            b.value2531 = 2531;\n            b.value2532 = 2532;\n            b.value2533 = 2533;\n            b.value2534 = 2534;\n            b.value2535 = 2535;\n            b.value2536 = 2536;\n            b.value2537 = 2537;\n            b.value2538 = 2538;\n            b.value2539 = 2539;\n            b.value2540 = 2540;\n            b.value2541 = 2541;\n            b.value2542 = 2542;\n            b.value2543 = 2543;\n            b.value2544 = 2544;\n            b.value2545 = 2545;\n            b.value2546 = 2546;\n            b.value2547 = 2547;\n            b.value2548 = 2548;\n            b.value2549 = 2549;\n            b.value2550 = 2550;\n            b.value2551 = 2551;\n            b.value2552 = 2552;\n            b.value2553 = 2553;\n            b.value2554 = 2554;\n            b.value2555 = 2555;\n            b.value2556 = 2556;\n            b.value2557 = 2557;\n            b.value2558 = 2558;\n            b.value2559 = 2559;\n            b.value2560 = 2560;\n            b.value2561 = 2561;\n            b.value2562 = 2562;\n            b.value2563 = 2563;\n            b.value2564 = 2564;\n            b.value2565 = 2565;\n            b.value2566 = 2566;\n            b.value2567 = 2567;\n            b.value2568 = 2568;\n            b.value2569 = 2569;\n            b.value2570 = 2570;\n            b.value2571 = 2571;\n            b.value2572 = 2572;\n            b.value2573 = 2573;\n            b.value2574 = 2574;\n            b.value2575 = 2575;\n            b.value2576 = 2576;\n            b.value2577 = 2577;\n            b.value2578 = 2578;\n            b.value2579 = 2579;\n            b.value2580 = 2580;\n            b.value2581 = 2581;\n            b.value2582 = 2582;\n            b.value2583 = 2583;\n            b.value2584 = 2584;\n            b.value2585 = 2585;\n            b.value2586 = 2586;\n            b.value2587 = 2587;\n            b.value2588 = 2588;\n            b.value2589 = 2589;\n            b.value2590 = 2590;\n            b.value2591 = 2591;\n            b.value2592 = 2592;\n            b.value2593 = 2593;\n            b.value2594 = 2594;\n            b.value2595 = 2595;\n            b.value2596 = 2596;\n            b.value2597 = 2597;\n            b.value2598 = 2598;\n            b.value2599 = 2599;\n            b.value2600 = 2600;\n            b.value2601 = 2601;\n            b.value2602 = 2602;\n            b.value2603 = 2603;\n            b.value2604 = 2604;\n            b.value2605 = 2605;\n            b.value2606 = 2606;\n            b.value2607 = 2607;\n            b.value2608 = 2608;\n            b.value2609 = 2609;\n            b.value2610 = 2610;\n            b.value2611 = 2611;\n            b.value2612 = 2612;\n            b.value2613 = 2613;\n            b.value2614 = 2614;\n            b.value2615 = 2615;\n            b.value2616 = 2616;\n            b.value2617 = 2617;\n            b.value2618 = 2618;\n            b.value2619 = 2619;\n            b.value2620 = 2620;\n            b.value2621 = 2621;\n            b.value2622 = 2622;\n            b.value2623 = 2623;\n            b.value2624 = 2624;\n            b.value2625 = 2625;\n            b.value2626 = 2626;\n            b.value2627 = 2627;\n            b.value2628 = 2628;\n            b.value2629 = 2629;\n            b.value2630 = 2630;\n            b.value2631 = 2631;\n            b.value2632 = 2632;\n            b.value2633 = 2633;\n            b.value2634 = 2634;\n            b.value2635 = 2635;\n            b.value2636 = 2636;\n            b.value2637 = 2637;\n            b.value2638 = 2638;\n            b.value2639 = 2639;\n            b.value2640 = 2640;\n            b.value2641 = 2641;\n            b.value2642 = 2642;\n            b.value2643 = 2643;\n            b.value2644 = 2644;\n            b.value2645 = 2645;\n            b.value2646 = 2646;\n            b.value2647 = 2647;\n            b.value2648 = 2648;\n            b.value2649 = 2649;\n            b.value2650 = 2650;\n            b.value2651 = 2651;\n            b.value2652 = 2652;\n            b.value2653 = 2653;\n            b.value2654 = 2654;\n            b.value2655 = 2655;\n            b.value2656 = 2656;\n            b.value2657 = 2657;\n            b.value2658 = 2658;\n            b.value2659 = 2659;\n            b.value2660 = 2660;\n            b.value2661 = 2661;\n            b.value2662 = 2662;\n            b.value2663 = 2663;\n            b.value2664 = 2664;\n            b.value2665 = 2665;\n            b.value2666 = 2666;\n            b.value2667 = 2667;\n            b.value2668 = 2668;\n            b.value2669 = 2669;\n            b.value2670 = 2670;\n            b.value2671 = 2671;\n            b.value2672 = 2672;\n            b.value2673 = 2673;\n            b.value2674 = 2674;\n            b.value2675 = 2675;\n            b.value2676 = 2676;\n            b.value2677 = 2677;\n            b.value2678 = 2678;\n            b.value2679 = 2679;\n            b.value2680 = 2680;\n            b.value2681 = 2681;\n            b.value2682 = 2682;\n            b.value2683 = 2683;\n            b.value2684 = 2684;\n            b.value2685 = 2685;\n            b.value2686 = 2686;\n            b.value2687 = 2687;\n            b.value2688 = 2688;\n            b.value2689 = 2689;\n            b.value2690 = 2690;\n            b.value2691 = 2691;\n            b.value2692 = 2692;\n            b.value2693 = 2693;\n            b.value2694 = 2694;\n            b.value2695 = 2695;\n            b.value2696 = 2696;\n            b.value2697 = 2697;\n            b.value2698 = 2698;\n            b.value2699 = 2699;\n            b.value2700 = 2700;\n            b.value2701 = 2701;\n            b.value2702 = 2702;\n            b.value2703 = 2703;\n            b.value2704 = 2704;\n            b.value2705 = 2705;\n            b.value2706 = 2706;\n            b.value2707 = 2707;\n            b.value2708 = 2708;\n            b.value2709 = 2709;\n            b.value2710 = 2710;\n            b.value2711 = 2711;\n            b.value2712 = 2712;\n            b.value2713 = 2713;\n            b.value2714 = 2714;\n            b.value2715 = 2715;\n            b.value2716 = 2716;\n            b.value2717 = 2717;\n            b.value2718 = 2718;\n            b.value2719 = 2719;\n            b.value2720 = 2720;\n            b.value2721 = 2721;\n            b.value2722 = 2722;\n            b.value2723 = 2723;\n            b.value2724 = 2724;\n            b.value2725 = 2725;\n            b.value2726 = 2726;\n            b.value2727 = 2727;\n            b.value2728 = 2728;\n            b.value2729 = 2729;\n            b.value2730 = 2730;\n            b.value2731 = 2731;\n            b.value2732 = 2732;\n            b.value2733 = 2733;\n            b.value2734 = 2734;\n            b.value2735 = 2735;\n            b.value2736 = 2736;\n            b.value2737 = 2737;\n            b.value2738 = 2738;\n            b.value2739 = 2739;\n            b.value2740 = 2740;\n            b.value2741 = 2741;\n            b.value2742 = 2742;\n            b.value2743 = 2743;\n            b.value2744 = 2744;\n            b.value2745 = 2745;\n            b.value2746 = 2746;\n            b.value2747 = 2747;\n            b.value2748 = 2748;\n            b.value2749 = 2749;\n            b.value2750 = 2750;\n            b.value2751 = 2751;\n            b.value2752 = 2752;\n            b.value2753 = 2753;\n            b.value2754 = 2754;\n            b.value2755 = 2755;\n            b.value2756 = 2756;\n            b.value2757 = 2757;\n            b.value2758 = 2758;\n            b.value2759 = 2759;\n            b.value2760 = 2760;\n            b.value2761 = 2761;\n            b.value2762 = 2762;\n            b.value2763 = 2763;\n            b.value2764 = 2764;\n            b.value2765 = 2765;\n            b.value2766 = 2766;\n            b.value2767 = 2767;\n            b.value2768 = 2768;\n            b.value2769 = 2769;\n            b.value2770 = 2770;\n            b.value2771 = 2771;\n            b.value2772 = 2772;\n            b.value2773 = 2773;\n            b.value2774 = 2774;\n            b.value2775 = 2775;\n            b.value2776 = 2776;\n            b.value2777 = 2777;\n            b.value2778 = 2778;\n            b.value2779 = 2779;\n            b.value2780 = 2780;\n            b.value2781 = 2781;\n            b.value2782 = 2782;\n            b.value2783 = 2783;\n            b.value2784 = 2784;\n            b.value2785 = 2785;\n            b.value2786 = 2786;\n            b.value2787 = 2787;\n            b.value2788 = 2788;\n            b.value2789 = 2789;\n            b.value2790 = 2790;\n            b.value2791 = 2791;\n            b.value2792 = 2792;\n            b.value2793 = 2793;\n            b.value2794 = 2794;\n            b.value2795 = 2795;\n            b.value2796 = 2796;\n            b.value2797 = 2797;\n            b.value2798 = 2798;\n            b.value2799 = 2799;\n            b.value2800 = 2800;\n            b.value2801 = 2801;\n            b.value2802 = 2802;\n            b.value2803 = 2803;\n            b.value2804 = 2804;\n            b.value2805 = 2805;\n            b.value2806 = 2806;\n            b.value2807 = 2807;\n            b.value2808 = 2808;\n            b.value2809 = 2809;\n            b.value2810 = 2810;\n            b.value2811 = 2811;\n            b.value2812 = 2812;\n            b.value2813 = 2813;\n            b.value2814 = 2814;\n            b.value2815 = 2815;\n            b.value2816 = 2816;\n            b.value2817 = 2817;\n            b.value2818 = 2818;\n            b.value2819 = 2819;\n            b.value2820 = 2820;\n            b.value2821 = 2821;\n            b.value2822 = 2822;\n            b.value2823 = 2823;\n            b.value2824 = 2824;\n            b.value2825 = 2825;\n            b.value2826 = 2826;\n            b.value2827 = 2827;\n            b.value2828 = 2828;\n            b.value2829 = 2829;\n            b.value2830 = 2830;\n            b.value2831 = 2831;\n            b.value2832 = 2832;\n            b.value2833 = 2833;\n            b.value2834 = 2834;\n            b.value2835 = 2835;\n            b.value2836 = 2836;\n            b.value2837 = 2837;\n            b.value2838 = 2838;\n            b.value2839 = 2839;\n            b.value2840 = 2840;\n            b.value2841 = 2841;\n            b.value2842 = 2842;\n            b.value2843 = 2843;\n            b.value2844 = 2844;\n            b.value2845 = 2845;\n            b.value2846 = 2846;\n            b.value2847 = 2847;\n            b.value2848 = 2848;\n            b.value2849 = 2849;\n            b.value2850 = 2850;\n            b.value2851 = 2851;\n            b.value2852 = 2852;\n            b.value2853 = 2853;\n            b.value2854 = 2854;\n            b.value2855 = 2855;\n            b.value2856 = 2856;\n            b.value2857 = 2857;\n            b.value2858 = 2858;\n            b.value2859 = 2859;\n            b.value2860 = 2860;\n            b.value2861 = 2861;\n            b.value2862 = 2862;\n            b.value2863 = 2863;\n            b.value2864 = 2864;\n            b.value2865 = 2865;\n            b.value2866 = 2866;\n            b.value2867 = 2867;\n            b.value2868 = 2868;\n            b.value2869 = 2869;\n            b.value2870 = 2870;\n            b.value2871 = 2871;\n            b.value2872 = 2872;\n            b.value2873 = 2873;\n            b.value2874 = 2874;\n            b.value2875 = 2875;\n            b.value2876 = 2876;\n            b.value2877 = 2877;\n            b.value2878 = 2878;\n            b.value2879 = 2879;\n            b.value2880 = 2880;\n            b.value2881 = 2881;\n            b.value2882 = 2882;\n            b.value2883 = 2883;\n            b.value2884 = 2884;\n            b.value2885 = 2885;\n            b.value2886 = 2886;\n            b.value2887 = 2887;\n            b.value2888 = 2888;\n            b.value2889 = 2889;\n            b.value2890 = 2890;\n            b.value2891 = 2891;\n            b.value2892 = 2892;\n            b.value2893 = 2893;\n            b.value2894 = 2894;\n            b.value2895 = 2895;\n            b.value2896 = 2896;\n            b.value2897 = 2897;\n            b.value2898 = 2898;\n            b.value2899 = 2899;\n            b.value2900 = 2900;\n            b.value2901 = 2901;\n            b.value2902 = 2902;\n            b.value2903 = 2903;\n            b.value2904 = 2904;\n            b.value2905 = 2905;\n            b.value2906 = 2906;\n            b.value2907 = 2907;\n            b.value2908 = 2908;\n            b.value2909 = 2909;\n            b.value2910 = 2910;\n            b.value2911 = 2911;\n            b.value2912 = 2912;\n            b.value2913 = 2913;\n            b.value2914 = 2914;\n            b.value2915 = 2915;\n            b.value2916 = 2916;\n            b.value2917 = 2917;\n            b.value2918 = 2918;\n            b.value2919 = 2919;\n            b.value2920 = 2920;\n            b.value2921 = 2921;\n            b.value2922 = 2922;\n            b.value2923 = 2923;\n            b.value2924 = 2924;\n            b.value2925 = 2925;\n            b.value2926 = 2926;\n            b.value2927 = 2927;\n            b.value2928 = 2928;\n            b.value2929 = 2929;\n            b.value2930 = 2930;\n            b.value2931 = 2931;\n            b.value2932 = 2932;\n            b.value2933 = 2933;\n            b.value2934 = 2934;\n            b.value2935 = 2935;\n            b.value2936 = 2936;\n            b.value2937 = 2937;\n            b.value2938 = 2938;\n            b.value2939 = 2939;\n            b.value2940 = 2940;\n            b.value2941 = 2941;\n            b.value2942 = 2942;\n            b.value2943 = 2943;\n            b.value2944 = 2944;\n            b.value2945 = 2945;\n            b.value2946 = 2946;\n            b.value2947 = 2947;\n            b.value2948 = 2948;\n            b.value2949 = 2949;\n            b.value2950 = 2950;\n            b.value2951 = 2951;\n            b.value2952 = 2952;\n            b.value2953 = 2953;\n            b.value2954 = 2954;\n            b.value2955 = 2955;\n            b.value2956 = 2956;\n            b.value2957 = 2957;\n            b.value2958 = 2958;\n            b.value2959 = 2959;\n            b.value2960 = 2960;\n            b.value2961 = 2961;\n            b.value2962 = 2962;\n            b.value2963 = 2963;\n            b.value2964 = 2964;\n            b.value2965 = 2965;\n            b.value2966 = 2966;\n            b.value2967 = 2967;\n            b.value2968 = 2968;\n            b.value2969 = 2969;\n            b.value2970 = 2970;\n            b.value2971 = 2971;\n            b.value2972 = 2972;\n            b.value2973 = 2973;\n            b.value2974 = 2974;\n            b.value2975 = 2975;\n            b.value2976 = 2976;\n            b.value2977 = 2977;\n            b.value2978 = 2978;\n            b.value2979 = 2979;\n            b.value2980 = 2980;\n            b.value2981 = 2981;\n            b.value2982 = 2982;\n            b.value2983 = 2983;\n            b.value2984 = 2984;\n            b.value2985 = 2985;\n            b.value2986 = 2986;\n            b.value2987 = 2987;\n            b.value2988 = 2988;\n            b.value2989 = 2989;\n            b.value2990 = 2990;\n            b.value2991 = 2991;\n            b.value2992 = 2992;\n            b.value2993 = 2993;\n            b.value2994 = 2994;\n            b.value2995 = 2995;\n            b.value2996 = 2996;\n            b.value2997 = 2997;\n            b.value2998 = 2998;\n            b.value2999 = 2999;\n            b.value3000 = 3000;\n            b.value3001 = 3001;\n            b.value3002 = 3002;\n            b.value3003 = 3003;\n            b.value3004 = 3004;\n            b.value3005 = 3005;\n            b.value3006 = 3006;\n            b.value3007 = 3007;\n            b.value3008 = 3008;\n            b.value3009 = 3009;\n            b.value3010 = 3010;\n            b.value3011 = 3011;\n            b.value3012 = 3012;\n            b.value3013 = 3013;\n            b.value3014 = 3014;\n            b.value3015 = 3015;\n            b.value3016 = 3016;\n            b.value3017 = 3017;\n            b.value3018 = 3018;\n            b.value3019 = 3019;\n            b.value3020 = 3020;\n            b.value3021 = 3021;\n            b.value3022 = 3022;\n            b.value3023 = 3023;\n            b.value3024 = 3024;\n            b.value3025 = 3025;\n            b.value3026 = 3026;\n            b.value3027 = 3027;\n            b.value3028 = 3028;\n            b.value3029 = 3029;\n            b.value3030 = 3030;\n            b.value3031 = 3031;\n            b.value3032 = 3032;\n            b.value3033 = 3033;\n            b.value3034 = 3034;\n            b.value3035 = 3035;\n            b.value3036 = 3036;\n            b.value3037 = 3037;\n            b.value3038 = 3038;\n            b.value3039 = 3039;\n            b.value3040 = 3040;\n            b.value3041 = 3041;\n            b.value3042 = 3042;\n            b.value3043 = 3043;\n            b.value3044 = 3044;\n            b.value3045 = 3045;\n            b.value3046 = 3046;\n            b.value3047 = 3047;\n            b.value3048 = 3048;\n            b.value3049 = 3049;\n            b.value3050 = 3050;\n            b.value3051 = 3051;\n            b.value3052 = 3052;\n            b.value3053 = 3053;\n            b.value3054 = 3054;\n            b.value3055 = 3055;\n            b.value3056 = 3056;\n            b.value3057 = 3057;\n            b.value3058 = 3058;\n            b.value3059 = 3059;\n            b.value3060 = 3060;\n            b.value3061 = 3061;\n            b.value3062 = 3062;\n            b.value3063 = 3063;\n            b.value3064 = 3064;\n            b.value3065 = 3065;\n            b.value3066 = 3066;\n            b.value3067 = 3067;\n            b.value3068 = 3068;\n            b.value3069 = 3069;\n            b.value3070 = 3070;\n            b.value3071 = 3071;\n            b.value3072 = 3072;\n            b.value3073 = 3073;\n            b.value3074 = 3074;\n            b.value3075 = 3075;\n            b.value3076 = 3076;\n            b.value3077 = 3077;\n            b.value3078 = 3078;\n            b.value3079 = 3079;\n            b.value3080 = 3080;\n            b.value3081 = 3081;\n            b.value3082 = 3082;\n            b.value3083 = 3083;\n            b.value3084 = 3084;\n            b.value3085 = 3085;\n            b.value3086 = 3086;\n            b.value3087 = 3087;\n            b.value3088 = 3088;\n            b.value3089 = 3089;\n            b.value3090 = 3090;\n            b.value3091 = 3091;\n            b.value3092 = 3092;\n            b.value3093 = 3093;\n            b.value3094 = 3094;\n            b.value3095 = 3095;\n            b.value3096 = 3096;\n            b.value3097 = 3097;\n            b.value3098 = 3098;\n            b.value3099 = 3099;\n            b.value3100 = 3100;\n            b.value3101 = 3101;\n            b.value3102 = 3102;\n            b.value3103 = 3103;\n            b.value3104 = 3104;\n            b.value3105 = 3105;\n            b.value3106 = 3106;\n            b.value3107 = 3107;\n            b.value3108 = 3108;\n            b.value3109 = 3109;\n            b.value3110 = 3110;\n            b.value3111 = 3111;\n            b.value3112 = 3112;\n            b.value3113 = 3113;\n            b.value3114 = 3114;\n            b.value3115 = 3115;\n            b.value3116 = 3116;\n            b.value3117 = 3117;\n            b.value3118 = 3118;\n            b.value3119 = 3119;\n            b.value3120 = 3120;\n            b.value3121 = 3121;\n            b.value3122 = 3122;\n            b.value3123 = 3123;\n            b.value3124 = 3124;\n            b.value3125 = 3125;\n            b.value3126 = 3126;\n            b.value3127 = 3127;\n            b.value3128 = 3128;\n            b.value3129 = 3129;\n            b.value3130 = 3130;\n            b.value3131 = 3131;\n            b.value3132 = 3132;\n            b.value3133 = 3133;\n            b.value3134 = 3134;\n            b.value3135 = 3135;\n            b.value3136 = 3136;\n            b.value3137 = 3137;\n            b.value3138 = 3138;\n            b.value3139 = 3139;\n            b.value3140 = 3140;\n            b.value3141 = 3141;\n            b.value3142 = 3142;\n            b.value3143 = 3143;\n            b.value3144 = 3144;\n            b.value3145 = 3145;\n            b.value3146 = 3146;\n            b.value3147 = 3147;\n            b.value3148 = 3148;\n            b.value3149 = 3149;\n            b.value3150 = 3150;\n            b.value3151 = 3151;\n            b.value3152 = 3152;\n            b.value3153 = 3153;\n            b.value3154 = 3154;\n            b.value3155 = 3155;\n            b.value3156 = 3156;\n            b.value3157 = 3157;\n            b.value3158 = 3158;\n            b.value3159 = 3159;\n            b.value3160 = 3160;\n            b.value3161 = 3161;\n            b.value3162 = 3162;\n            b.value3163 = 3163;\n            b.value3164 = 3164;\n            b.value3165 = 3165;\n            b.value3166 = 3166;\n            b.value3167 = 3167;\n            b.value3168 = 3168;\n            b.value3169 = 3169;\n            b.value3170 = 3170;\n            b.value3171 = 3171;\n            b.value3172 = 3172;\n            b.value3173 = 3173;\n            b.value3174 = 3174;\n            b.value3175 = 3175;\n            b.value3176 = 3176;\n            b.value3177 = 3177;\n            b.value3178 = 3178;\n            b.value3179 = 3179;\n            b.value3180 = 3180;\n            b.value3181 = 3181;\n            b.value3182 = 3182;\n            b.value3183 = 3183;\n            b.value3184 = 3184;\n            b.value3185 = 3185;\n            b.value3186 = 3186;\n            b.value3187 = 3187;\n            b.value3188 = 3188;\n            b.value3189 = 3189;\n            b.value3190 = 3190;\n            b.value3191 = 3191;\n            b.value3192 = 3192;\n            b.value3193 = 3193;\n            b.value3194 = 3194;\n            b.value3195 = 3195;\n            b.value3196 = 3196;\n            b.value3197 = 3197;\n            b.value3198 = 3198;\n            b.value3199 = 3199;\n            b.value3200 = 3200;\n            b.value3201 = 3201;\n            b.value3202 = 3202;\n            b.value3203 = 3203;\n            b.value3204 = 3204;\n            b.value3205 = 3205;\n            b.value3206 = 3206;\n            b.value3207 = 3207;\n            b.value3208 = 3208;\n            b.value3209 = 3209;\n            b.value3210 = 3210;\n            b.value3211 = 3211;\n            b.value3212 = 3212;\n            b.value3213 = 3213;\n            b.value3214 = 3214;\n            b.value3215 = 3215;\n            b.value3216 = 3216;\n            b.value3217 = 3217;\n            b.value3218 = 3218;\n            b.value3219 = 3219;\n            b.value3220 = 3220;\n            b.value3221 = 3221;\n            b.value3222 = 3222;\n            b.value3223 = 3223;\n            b.value3224 = 3224;\n            b.value3225 = 3225;\n            b.value3226 = 3226;\n            b.value3227 = 3227;\n            b.value3228 = 3228;\n            b.value3229 = 3229;\n            b.value3230 = 3230;\n            b.value3231 = 3231;\n            b.value3232 = 3232;\n            b.value3233 = 3233;\n            b.value3234 = 3234;\n            b.value3235 = 3235;\n            b.value3236 = 3236;\n            b.value3237 = 3237;\n            b.value3238 = 3238;\n            b.value3239 = 3239;\n            b.value3240 = 3240;\n            b.value3241 = 3241;\n            b.value3242 = 3242;\n            b.value3243 = 3243;\n            b.value3244 = 3244;\n            b.value3245 = 3245;\n            b.value3246 = 3246;\n            b.value3247 = 3247;\n            b.value3248 = 3248;\n            b.value3249 = 3249;\n            b.value3250 = 3250;\n            b.value3251 = 3251;\n            b.value3252 = 3252;\n            b.value3253 = 3253;\n            b.value3254 = 3254;\n            b.value3255 = 3255;\n            b.value3256 = 3256;\n            b.value3257 = 3257;\n            b.value3258 = 3258;\n            b.value3259 = 3259;\n            b.value3260 = 3260;\n            b.value3261 = 3261;\n            b.value3262 = 3262;\n            b.value3263 = 3263;\n            b.value3264 = 3264;\n            b.value3265 = 3265;\n            b.value3266 = 3266;\n            b.value3267 = 3267;\n            b.value3268 = 3268;\n            b.value3269 = 3269;\n            b.value3270 = 3270;\n            b.value3271 = 3271;\n            b.value3272 = 3272;\n            b.value3273 = 3273;\n            b.value3274 = 3274;\n            b.value3275 = 3275;\n            b.value3276 = 3276;\n            b.value3277 = 3277;\n            b.value3278 = 3278;\n            b.value3279 = 3279;\n            b.value3280 = 3280;\n            b.value3281 = 3281;\n            b.value3282 = 3282;\n            b.value3283 = 3283;\n            b.value3284 = 3284;\n            b.value3285 = 3285;\n            b.value3286 = 3286;\n            b.value3287 = 3287;\n            b.value3288 = 3288;\n            b.value3289 = 3289;\n            b.value3290 = 3290;\n            b.value3291 = 3291;\n            b.value3292 = 3292;\n            b.value3293 = 3293;\n            b.value3294 = 3294;\n            b.value3295 = 3295;\n            b.value3296 = 3296;\n            b.value3297 = 3297;\n            b.value3298 = 3298;\n            b.value3299 = 3299;\n            b.value3300 = 3300;\n            b.value3301 = 3301;\n            b.value3302 = 3302;\n            b.value3303 = 3303;\n            b.value3304 = 3304;\n            b.value3305 = 3305;\n            b.value3306 = 3306;\n            b.value3307 = 3307;\n            b.value3308 = 3308;\n            b.value3309 = 3309;\n            b.value3310 = 3310;\n            b.value3311 = 3311;\n            b.value3312 = 3312;\n            b.value3313 = 3313;\n            b.value3314 = 3314;\n            b.value3315 = 3315;\n            b.value3316 = 3316;\n            b.value3317 = 3317;\n            b.value3318 = 3318;\n            b.value3319 = 3319;\n            b.value3320 = 3320;\n            b.value3321 = 3321;\n            b.value3322 = 3322;\n            b.value3323 = 3323;\n            b.value3324 = 3324;\n            b.value3325 = 3325;\n            b.value3326 = 3326;\n            b.value3327 = 3327;\n            b.value3328 = 3328;\n            b.value3329 = 3329;\n            b.value3330 = 3330;\n            b.value3331 = 3331;\n            b.value3332 = 3332;\n            b.value3333 = 3333;\n            b.value3334 = 3334;\n            b.value3335 = 3335;\n            b.value3336 = 3336;\n            b.value3337 = 3337;\n            b.value3338 = 3338;\n            b.value3339 = 3339;\n            b.value3340 = 3340;\n            b.value3341 = 3341;\n            b.value3342 = 3342;\n            b.value3343 = 3343;\n            b.value3344 = 3344;\n            b.value3345 = 3345;\n            b.value3346 = 3346;\n            b.value3347 = 3347;\n            b.value3348 = 3348;\n            b.value3349 = 3349;\n            b.value3350 = 3350;\n            b.value3351 = 3351;\n            b.value3352 = 3352;\n            b.value3353 = 3353;\n            b.value3354 = 3354;\n            b.value3355 = 3355;\n            b.value3356 = 3356;\n            b.value3357 = 3357;\n            b.value3358 = 3358;\n            b.value3359 = 3359;\n            b.value3360 = 3360;\n            b.value3361 = 3361;\n            b.value3362 = 3362;\n            b.value3363 = 3363;\n            b.value3364 = 3364;\n            b.value3365 = 3365;\n            b.value3366 = 3366;\n            b.value3367 = 3367;\n            b.value3368 = 3368;\n            b.value3369 = 3369;\n            b.value3370 = 3370;\n            b.value3371 = 3371;\n            b.value3372 = 3372;\n            b.value3373 = 3373;\n            b.value3374 = 3374;\n            b.value3375 = 3375;\n            b.value3376 = 3376;\n            b.value3377 = 3377;\n            b.value3378 = 3378;\n            b.value3379 = 3379;\n            b.value3380 = 3380;\n            b.value3381 = 3381;\n            b.value3382 = 3382;\n            b.value3383 = 3383;\n            b.value3384 = 3384;\n            b.value3385 = 3385;\n            b.value3386 = 3386;\n            b.value3387 = 3387;\n            b.value3388 = 3388;\n            b.value3389 = 3389;\n            b.value3390 = 3390;\n            b.value3391 = 3391;\n            b.value3392 = 3392;\n            b.value3393 = 3393;\n            b.value3394 = 3394;\n            b.value3395 = 3395;\n            b.value3396 = 3396;\n            b.value3397 = 3397;\n            b.value3398 = 3398;\n            b.value3399 = 3399;\n            b.value3400 = 3400;\n            b.value3401 = 3401;\n            b.value3402 = 3402;\n            b.value3403 = 3403;\n            b.value3404 = 3404;\n            b.value3405 = 3405;\n            b.value3406 = 3406;\n            b.value3407 = 3407;\n            b.value3408 = 3408;\n            b.value3409 = 3409;\n            b.value3410 = 3410;\n            b.value3411 = 3411;\n            b.value3412 = 3412;\n            b.value3413 = 3413;\n            b.value3414 = 3414;\n            b.value3415 = 3415;\n            b.value3416 = 3416;\n            b.value3417 = 3417;\n            b.value3418 = 3418;\n            b.value3419 = 3419;\n            b.value3420 = 3420;\n            b.value3421 = 3421;\n            b.value3422 = 3422;\n            b.value3423 = 3423;\n            b.value3424 = 3424;\n            b.value3425 = 3425;\n            b.value3426 = 3426;\n            b.value3427 = 3427;\n            b.value3428 = 3428;\n            b.value3429 = 3429;\n            b.value3430 = 3430;\n            b.value3431 = 3431;\n            b.value3432 = 3432;\n            b.value3433 = 3433;\n            b.value3434 = 3434;\n            b.value3435 = 3435;\n            b.value3436 = 3436;\n            b.value3437 = 3437;\n            b.value3438 = 3438;\n            b.value3439 = 3439;\n            b.value3440 = 3440;\n            b.value3441 = 3441;\n            b.value3442 = 3442;\n            b.value3443 = 3443;\n            b.value3444 = 3444;\n            b.value3445 = 3445;\n            b.value3446 = 3446;\n            b.value3447 = 3447;\n            b.value3448 = 3448;\n            b.value3449 = 3449;\n            b.value3450 = 3450;\n            b.value3451 = 3451;\n            b.value3452 = 3452;\n            b.value3453 = 3453;\n            b.value3454 = 3454;\n            b.value3455 = 3455;\n            b.value3456 = 3456;\n            b.value3457 = 3457;\n            b.value3458 = 3458;\n            b.value3459 = 3459;\n            b.value3460 = 3460;\n            b.value3461 = 3461;\n            b.value3462 = 3462;\n            b.value3463 = 3463;\n            b.value3464 = 3464;\n            b.value3465 = 3465;\n            b.value3466 = 3466;\n            b.value3467 = 3467;\n            b.value3468 = 3468;\n            b.value3469 = 3469;\n            b.value3470 = 3470;\n            b.value3471 = 3471;\n            b.value3472 = 3472;\n            b.value3473 = 3473;\n            b.value3474 = 3474;\n            b.value3475 = 3475;\n            b.value3476 = 3476;\n            b.value3477 = 3477;\n            b.value3478 = 3478;\n            b.value3479 = 3479;\n            b.value3480 = 3480;\n            b.value3481 = 3481;\n            b.value3482 = 3482;\n            b.value3483 = 3483;\n            b.value3484 = 3484;\n            b.value3485 = 3485;\n            b.value3486 = 3486;\n            b.value3487 = 3487;\n            b.value3488 = 3488;\n            b.value3489 = 3489;\n            b.value3490 = 3490;\n            b.value3491 = 3491;\n            b.value3492 = 3492;\n            b.value3493 = 3493;\n            b.value3494 = 3494;\n            b.value3495 = 3495;\n            b.value3496 = 3496;\n            b.value3497 = 3497;\n            b.value3498 = 3498;\n            b.value3499 = 3499;\n            b.value3500 = 3500;\n            b.value3501 = 3501;\n            b.value3502 = 3502;\n            b.value3503 = 3503;\n            b.value3504 = 3504;\n            b.value3505 = 3505;\n            b.value3506 = 3506;\n            b.value3507 = 3507;\n            b.value3508 = 3508;\n            b.value3509 = 3509;\n            b.value3510 = 3510;\n            b.value3511 = 3511;\n            b.value3512 = 3512;\n            b.value3513 = 3513;\n            b.value3514 = 3514;\n            b.value3515 = 3515;\n            b.value3516 = 3516;\n            b.value3517 = 3517;\n            b.value3518 = 3518;\n            b.value3519 = 3519;\n            b.value3520 = 3520;\n            b.value3521 = 3521;\n            b.value3522 = 3522;\n            b.value3523 = 3523;\n            b.value3524 = 3524;\n            b.value3525 = 3525;\n            b.value3526 = 3526;\n            b.value3527 = 3527;\n            b.value3528 = 3528;\n            b.value3529 = 3529;\n            b.value3530 = 3530;\n            b.value3531 = 3531;\n            b.value3532 = 3532;\n            b.value3533 = 3533;\n            b.value3534 = 3534;\n            b.value3535 = 3535;\n            b.value3536 = 3536;\n            b.value3537 = 3537;\n            b.value3538 = 3538;\n            b.value3539 = 3539;\n            b.value3540 = 3540;\n            b.value3541 = 3541;\n            b.value3542 = 3542;\n            b.value3543 = 3543;\n            b.value3544 = 3544;\n            b.value3545 = 3545;\n            b.value3546 = 3546;\n            b.value3547 = 3547;\n            b.value3548 = 3548;\n            b.value3549 = 3549;\n            b.value3550 = 3550;\n            b.value3551 = 3551;\n            b.value3552 = 3552;\n            b.value3553 = 3553;\n            b.value3554 = 3554;\n            b.value3555 = 3555;\n            b.value3556 = 3556;\n            b.value3557 = 3557;\n            b.value3558 = 3558;\n            b.value3559 = 3559;\n            b.value3560 = 3560;\n            b.value3561 = 3561;\n            b.value3562 = 3562;\n            b.value3563 = 3563;\n            b.value3564 = 3564;\n            b.value3565 = 3565;\n            b.value3566 = 3566;\n            b.value3567 = 3567;\n            b.value3568 = 3568;\n            b.value3569 = 3569;\n            b.value3570 = 3570;\n            b.value3571 = 3571;\n            b.value3572 = 3572;\n            b.value3573 = 3573;\n            b.value3574 = 3574;\n            b.value3575 = 3575;\n            b.value3576 = 3576;\n            b.value3577 = 3577;\n            b.value3578 = 3578;\n            b.value3579 = 3579;\n            b.value3580 = 3580;\n            b.value3581 = 3581;\n            b.value3582 = 3582;\n            b.value3583 = 3583;\n            b.value3584 = 3584;\n            b.value3585 = 3585;\n            b.value3586 = 3586;\n            b.value3587 = 3587;\n            b.value3588 = 3588;\n            b.value3589 = 3589;\n            b.value3590 = 3590;\n            b.value3591 = 3591;\n            b.value3592 = 3592;\n            b.value3593 = 3593;\n            b.value3594 = 3594;\n            b.value3595 = 3595;\n            b.value3596 = 3596;\n            b.value3597 = 3597;\n            b.value3598 = 3598;\n            b.value3599 = 3599;\n            b.value3600 = 3600;\n            b.value3601 = 3601;\n            b.value3602 = 3602;\n            b.value3603 = 3603;\n            b.value3604 = 3604;\n            b.value3605 = 3605;\n            b.value3606 = 3606;\n            b.value3607 = 3607;\n            b.value3608 = 3608;\n            b.value3609 = 3609;\n            b.value3610 = 3610;\n            b.value3611 = 3611;\n            b.value3612 = 3612;\n            b.value3613 = 3613;\n            b.value3614 = 3614;\n            b.value3615 = 3615;\n            b.value3616 = 3616;\n            b.value3617 = 3617;\n            b.value3618 = 3618;\n            b.value3619 = 3619;\n            b.value3620 = 3620;\n            b.value3621 = 3621;\n            b.value3622 = 3622;\n            b.value3623 = 3623;\n            b.value3624 = 3624;\n            b.value3625 = 3625;\n            b.value3626 = 3626;\n            b.value3627 = 3627;\n            b.value3628 = 3628;\n            b.value3629 = 3629;\n            b.value3630 = 3630;\n            b.value3631 = 3631;\n            b.value3632 = 3632;\n            b.value3633 = 3633;\n            b.value3634 = 3634;\n            b.value3635 = 3635;\n            b.value3636 = 3636;\n            b.value3637 = 3637;\n            b.value3638 = 3638;\n            b.value3639 = 3639;\n            b.value3640 = 3640;\n            b.value3641 = 3641;\n            b.value3642 = 3642;\n            b.value3643 = 3643;\n            b.value3644 = 3644;\n            b.value3645 = 3645;\n            b.value3646 = 3646;\n            b.value3647 = 3647;\n            b.value3648 = 3648;\n            b.value3649 = 3649;\n            b.value3650 = 3650;\n            b.value3651 = 3651;\n            b.value3652 = 3652;\n            b.value3653 = 3653;\n            b.value3654 = 3654;\n            b.value3655 = 3655;\n            b.value3656 = 3656;\n            b.value3657 = 3657;\n            b.value3658 = 3658;\n            b.value3659 = 3659;\n            b.value3660 = 3660;\n            b.value3661 = 3661;\n            b.value3662 = 3662;\n            b.value3663 = 3663;\n            b.value3664 = 3664;\n            b.value3665 = 3665;\n            b.value3666 = 3666;\n            b.value3667 = 3667;\n            b.value3668 = 3668;\n            b.value3669 = 3669;\n            b.value3670 = 3670;\n            b.value3671 = 3671;\n            b.value3672 = 3672;\n            b.value3673 = 3673;\n            b.value3674 = 3674;\n            b.value3675 = 3675;\n            b.value3676 = 3676;\n            b.value3677 = 3677;\n            b.value3678 = 3678;\n            b.value3679 = 3679;\n            b.value3680 = 3680;\n            b.value3681 = 3681;\n            b.value3682 = 3682;\n            b.value3683 = 3683;\n            b.value3684 = 3684;\n            b.value3685 = 3685;\n            b.value3686 = 3686;\n            b.value3687 = 3687;\n            b.value3688 = 3688;\n            b.value3689 = 3689;\n            b.value3690 = 3690;\n            b.value3691 = 3691;\n            b.value3692 = 3692;\n            b.value3693 = 3693;\n            b.value3694 = 3694;\n            b.value3695 = 3695;\n            b.value3696 = 3696;\n            b.value3697 = 3697;\n            b.value3698 = 3698;\n            b.value3699 = 3699;\n            b.value3700 = 3700;\n            b.value3701 = 3701;\n            b.value3702 = 3702;\n            b.value3703 = 3703;\n            b.value3704 = 3704;\n            b.value3705 = 3705;\n            b.value3706 = 3706;\n            b.value3707 = 3707;\n            b.value3708 = 3708;\n            b.value3709 = 3709;\n            b.value3710 = 3710;\n            b.value3711 = 3711;\n            b.value3712 = 3712;\n            b.value3713 = 3713;\n            b.value3714 = 3714;\n            b.value3715 = 3715;\n            b.value3716 = 3716;\n            b.value3717 = 3717;\n            b.value3718 = 3718;\n            b.value3719 = 3719;\n            b.value3720 = 3720;\n            b.value3721 = 3721;\n            b.value3722 = 3722;\n            b.value3723 = 3723;\n            b.value3724 = 3724;\n            b.value3725 = 3725;\n            b.value3726 = 3726;\n            b.value3727 = 3727;\n            b.value3728 = 3728;\n            b.value3729 = 3729;\n            b.value3730 = 3730;\n            b.value3731 = 3731;\n            b.value3732 = 3732;\n            b.value3733 = 3733;\n            b.value3734 = 3734;\n            b.value3735 = 3735;\n            b.value3736 = 3736;\n            b.value3737 = 3737;\n            b.value3738 = 3738;\n            b.value3739 = 3739;\n            b.value3740 = 3740;\n            b.value3741 = 3741;\n            b.value3742 = 3742;\n            b.value3743 = 3743;\n            b.value3744 = 3744;\n            b.value3745 = 3745;\n            b.value3746 = 3746;\n            b.value3747 = 3747;\n            b.value3748 = 3748;\n            b.value3749 = 3749;\n            b.value3750 = 3750;\n            b.value3751 = 3751;\n            b.value3752 = 3752;\n            b.value3753 = 3753;\n            b.value3754 = 3754;\n            b.value3755 = 3755;\n            b.value3756 = 3756;\n            b.value3757 = 3757;\n            b.value3758 = 3758;\n            b.value3759 = 3759;\n            b.value3760 = 3760;\n            b.value3761 = 3761;\n            b.value3762 = 3762;\n            b.value3763 = 3763;\n            b.value3764 = 3764;\n            b.value3765 = 3765;\n            b.value3766 = 3766;\n            b.value3767 = 3767;\n            b.value3768 = 3768;\n            b.value3769 = 3769;\n            b.value3770 = 3770;\n            b.value3771 = 3771;\n            b.value3772 = 3772;\n            b.value3773 = 3773;\n            b.value3774 = 3774;\n            b.value3775 = 3775;\n            b.value3776 = 3776;\n            b.value3777 = 3777;\n            b.value3778 = 3778;\n            b.value3779 = 3779;\n            b.value3780 = 3780;\n            b.value3781 = 3781;\n            b.value3782 = 3782;\n            b.value3783 = 3783;\n            b.value3784 = 3784;\n            b.value3785 = 3785;\n            b.value3786 = 3786;\n            b.value3787 = 3787;\n            b.value3788 = 3788;\n            b.value3789 = 3789;\n            b.value3790 = 3790;\n            b.value3791 = 3791;\n            b.value3792 = 3792;\n            b.value3793 = 3793;\n            b.value3794 = 3794;\n            b.value3795 = 3795;\n            b.value3796 = 3796;\n            b.value3797 = 3797;\n            b.value3798 = 3798;\n            b.value3799 = 3799;\n            b.value3800 = 3800;\n            b.value3801 = 3801;\n            b.value3802 = 3802;\n            b.value3803 = 3803;\n            b.value3804 = 3804;\n            b.value3805 = 3805;\n            b.value3806 = 3806;\n            b.value3807 = 3807;\n            b.value3808 = 3808;\n            b.value3809 = 3809;\n            b.value3810 = 3810;\n            b.value3811 = 3811;\n            b.value3812 = 3812;\n            b.value3813 = 3813;\n            b.value3814 = 3814;\n            b.value3815 = 3815;\n            b.value3816 = 3816;\n            b.value3817 = 3817;\n            b.value3818 = 3818;\n            b.value3819 = 3819;\n            b.value3820 = 3820;\n            b.value3821 = 3821;\n            b.value3822 = 3822;\n            b.value3823 = 3823;\n            b.value3824 = 3824;\n            b.value3825 = 3825;\n            b.value3826 = 3826;\n            b.value3827 = 3827;\n            b.value3828 = 3828;\n            b.value3829 = 3829;\n            b.value3830 = 3830;\n            b.value3831 = 3831;\n            b.value3832 = 3832;\n            b.value3833 = 3833;\n            b.value3834 = 3834;\n            b.value3835 = 3835;\n            b.value3836 = 3836;\n            b.value3837 = 3837;\n            b.value3838 = 3838;\n            b.value3839 = 3839;\n            b.value3840 = 3840;\n            b.value3841 = 3841;\n            b.value3842 = 3842;\n            b.value3843 = 3843;\n            b.value3844 = 3844;\n            b.value3845 = 3845;\n            b.value3846 = 3846;\n            b.value3847 = 3847;\n            b.value3848 = 3848;\n            b.value3849 = 3849;\n            b.value3850 = 3850;\n            b.value3851 = 3851;\n            b.value3852 = 3852;\n            b.value3853 = 3853;\n            b.value3854 = 3854;\n            b.value3855 = 3855;\n            b.value3856 = 3856;\n            b.value3857 = 3857;\n            b.value3858 = 3858;\n            b.value3859 = 3859;\n            b.value3860 = 3860;\n            b.value3861 = 3861;\n            b.value3862 = 3862;\n            b.value3863 = 3863;\n            b.value3864 = 3864;\n            b.value3865 = 3865;\n            b.value3866 = 3866;\n            b.value3867 = 3867;\n            b.value3868 = 3868;\n            b.value3869 = 3869;\n            b.value3870 = 3870;\n            b.value3871 = 3871;\n            b.value3872 = 3872;\n            b.value3873 = 3873;\n            b.value3874 = 3874;\n            b.value3875 = 3875;\n            b.value3876 = 3876;\n            b.value3877 = 3877;\n            b.value3878 = 3878;\n            b.value3879 = 3879;\n            b.value3880 = 3880;\n            b.value3881 = 3881;\n            b.value3882 = 3882;\n            b.value3883 = 3883;\n            b.value3884 = 3884;\n            b.value3885 = 3885;\n            b.value3886 = 3886;\n            b.value3887 = 3887;\n            b.value3888 = 3888;\n            b.value3889 = 3889;\n            b.value3890 = 3890;\n            b.value3891 = 3891;\n            b.value3892 = 3892;\n            b.value3893 = 3893;\n            b.value3894 = 3894;\n            b.value3895 = 3895;\n            b.value3896 = 3896;\n            b.value3897 = 3897;\n            b.value3898 = 3898;\n            b.value3899 = 3899;\n            b.value3900 = 3900;\n            b.value3901 = 3901;\n            b.value3902 = 3902;\n            b.value3903 = 3903;\n            b.value3904 = 3904;\n            b.value3905 = 3905;\n            b.value3906 = 3906;\n            b.value3907 = 3907;\n            b.value3908 = 3908;\n            b.value3909 = 3909;\n            b.value3910 = 3910;\n            b.value3911 = 3911;\n            b.value3912 = 3912;\n            b.value3913 = 3913;\n            b.value3914 = 3914;\n            b.value3915 = 3915;\n            b.value3916 = 3916;\n            b.value3917 = 3917;\n            b.value3918 = 3918;\n            b.value3919 = 3919;\n            b.value3920 = 3920;\n            b.value3921 = 3921;\n            b.value3922 = 3922;\n            b.value3923 = 3923;\n            b.value3924 = 3924;\n            b.value3925 = 3925;\n            b.value3926 = 3926;\n            b.value3927 = 3927;\n            b.value3928 = 3928;\n            b.value3929 = 3929;\n            b.value3930 = 3930;\n            b.value3931 = 3931;\n            b.value3932 = 3932;\n            b.value3933 = 3933;\n            b.value3934 = 3934;\n            b.value3935 = 3935;\n            b.value3936 = 3936;\n            b.value3937 = 3937;\n            b.value3938 = 3938;\n            b.value3939 = 3939;\n            b.value3940 = 3940;\n            b.value3941 = 3941;\n            b.value3942 = 3942;\n            b.value3943 = 3943;\n            b.value3944 = 3944;\n            b.value3945 = 3945;\n            b.value3946 = 3946;\n            b.value3947 = 3947;\n            b.value3948 = 3948;\n            b.value3949 = 3949;\n            b.value3950 = 3950;\n            b.value3951 = 3951;\n            b.value3952 = 3952;\n            b.value3953 = 3953;\n            b.value3954 = 3954;\n            b.value3955 = 3955;\n            b.value3956 = 3956;\n            b.value3957 = 3957;\n            b.value3958 = 3958;\n            b.value3959 = 3959;\n            b.value3960 = 3960;\n            b.value3961 = 3961;\n            b.value3962 = 3962;\n            b.value3963 = 3963;\n            b.value3964 = 3964;\n            b.value3965 = 3965;\n            b.value3966 = 3966;\n            b.value3967 = 3967;\n            b.value3968 = 3968;\n            b.value3969 = 3969;\n            b.value3970 = 3970;\n            b.value3971 = 3971;\n            b.value3972 = 3972;\n            b.value3973 = 3973;\n            b.value3974 = 3974;\n            b.value3975 = 3975;\n            b.value3976 = 3976;\n            b.value3977 = 3977;\n            b.value3978 = 3978;\n            b.value3979 = 3979;\n            b.value3980 = 3980;\n            b.value3981 = 3981;\n            b.value3982 = 3982;\n            b.value3983 = 3983;\n            b.value3984 = 3984;\n            b.value3985 = 3985;\n            b.value3986 = 3986;\n            b.value3987 = 3987;\n            b.value3988 = 3988;\n            b.value3989 = 3989;\n            b.value3990 = 3990;\n            b.value3991 = 3991;\n            b.value3992 = 3992;\n            b.value3993 = 3993;\n            b.value3994 = 3994;\n            b.value3995 = 3995;\n            b.value3996 = 3996;\n            b.value3997 = 3997;\n            b.value3998 = 3998;\n            b.value3999 = 3999;\n            b.value4000 = 4000;\n            b.value4001 = 4001;\n            b.value4002 = 4002;\n            b.value4003 = 4003;\n            b.value4004 = 4004;\n            b.value4005 = 4005;\n            b.value4006 = 4006;\n            b.value4007 = 4007;\n            b.value4008 = 4008;\n            b.value4009 = 4009;\n            b.value4010 = 4010;\n            b.value4011 = 4011;\n            b.value4012 = 4012;\n            b.value4013 = 4013;\n            b.value4014 = 4014;\n            b.value4015 = 4015;\n            b.value4016 = 4016;\n            b.value4017 = 4017;\n            b.value4018 = 4018;\n            b.value4019 = 4019;\n            b.value4020 = 4020;\n            b.value4021 = 4021;\n            b.value4022 = 4022;\n            b.value4023 = 4023;\n            b.value4024 = 4024;\n            b.value4025 = 4025;\n            b.value4026 = 4026;\n            b.value4027 = 4027;\n            b.value4028 = 4028;\n            b.value4029 = 4029;\n            b.value4030 = 4030;\n            b.value4031 = 4031;\n            b.value4032 = 4032;\n            b.value4033 = 4033;\n            b.value4034 = 4034;\n            b.value4035 = 4035;\n            b.value4036 = 4036;\n            b.value4037 = 4037;\n            b.value4038 = 4038;\n            b.value4039 = 4039;\n            b.value4040 = 4040;\n            b.value4041 = 4041;\n            b.value4042 = 4042;\n            b.value4043 = 4043;\n            b.value4044 = 4044;\n            b.value4045 = 4045;\n            b.value4046 = 4046;\n            b.value4047 = 4047;\n            b.value4048 = 4048;\n            b.value4049 = 4049;\n            b.value4050 = 4050;\n            b.value4051 = 4051;\n            b.value4052 = 4052;\n            b.value4053 = 4053;\n            b.value4054 = 4054;\n            b.value4055 = 4055;\n            b.value4056 = 4056;\n            b.value4057 = 4057;\n            b.value4058 = 4058;\n            b.value4059 = 4059;\n            b.value4060 = 4060;\n            b.value4061 = 4061;\n            b.value4062 = 4062;\n            b.value4063 = 4063;\n            b.value4064 = 4064;\n            b.value4065 = 4065;\n            b.value4066 = 4066;\n            b.value4067 = 4067;\n            b.value4068 = 4068;\n            b.value4069 = 4069;\n            b.value4070 = 4070;\n            b.value4071 = 4071;\n            b.value4072 = 4072;\n            b.value4073 = 4073;\n            b.value4074 = 4074;\n            b.value4075 = 4075;\n            b.value4076 = 4076;\n            b.value4077 = 4077;\n            b.value4078 = 4078;\n            b.value4079 = 4079;\n            b.value4080 = 4080;\n            b.value4081 = 4081;\n            b.value4082 = 4082;\n            b.value4083 = 4083;\n            b.value4084 = 4084;\n            b.value4085 = 4085;\n            b.value4086 = 4086;\n            b.value4087 = 4087;\n            b.value4088 = 4088;\n            b.value4089 = 4089;\n            b.value4090 = 4090;\n            b.value4091 = 4091;\n            b.value4092 = 4092;\n            b.value4093 = 4093;\n            b.value4094 = 4094;\n            b.value4095 = 4095;\n            b.value4096 = 4096;\n            b.value4097 = 4097;\n            b.value4098 = 4098;\n            b.value4099 = 4099;\n            b.value4100 = 4100;\n            b.value4101 = 4101;\n            b.value4102 = 4102;\n            b.value4103 = 4103;\n            b.value4104 = 4104;\n            b.value4105 = 4105;\n            b.value4106 = 4106;\n            b.value4107 = 4107;\n            b.value4108 = 4108;\n            b.value4109 = 4109;\n            b.value4110 = 4110;\n            b.value4111 = 4111;\n            b.value4112 = 4112;\n            b.value4113 = 4113;\n            b.value4114 = 4114;\n            b.value4115 = 4115;\n            b.value4116 = 4116;\n            b.value4117 = 4117;\n            b.value4118 = 4118;\n            b.value4119 = 4119;\n            b.value4120 = 4120;\n            b.value4121 = 4121;\n            b.value4122 = 4122;\n            b.value4123 = 4123;\n            b.value4124 = 4124;\n            b.value4125 = 4125;\n            b.value4126 = 4126;\n            b.value4127 = 4127;\n            b.value4128 = 4128;\n            b.value4129 = 4129;\n            b.value4130 = 4130;\n            b.value4131 = 4131;\n            b.value4132 = 4132;\n            b.value4133 = 4133;\n            b.value4134 = 4134;\n            b.value4135 = 4135;\n            b.value4136 = 4136;\n            b.value4137 = 4137;\n            b.value4138 = 4138;\n            b.value4139 = 4139;\n            b.value4140 = 4140;\n            b.value4141 = 4141;\n            b.value4142 = 4142;\n            b.value4143 = 4143;\n            b.value4144 = 4144;\n            b.value4145 = 4145;\n            b.value4146 = 4146;\n            b.value4147 = 4147;\n            b.value4148 = 4148;\n            b.value4149 = 4149;\n            b.value4150 = 4150;\n            b.value4151 = 4151;\n            b.value4152 = 4152;\n            b.value4153 = 4153;\n            b.value4154 = 4154;\n            b.value4155 = 4155;\n            b.value4156 = 4156;\n            b.value4157 = 4157;\n            b.value4158 = 4158;\n            b.value4159 = 4159;\n            b.value4160 = 4160;\n            b.value4161 = 4161;\n            b.value4162 = 4162;\n            b.value4163 = 4163;\n            b.value4164 = 4164;\n            b.value4165 = 4165;\n            b.value4166 = 4166;\n            b.value4167 = 4167;\n            b.value4168 = 4168;\n            b.value4169 = 4169;\n            b.value4170 = 4170;\n            b.value4171 = 4171;\n            b.value4172 = 4172;\n            b.value4173 = 4173;\n            b.value4174 = 4174;\n            b.value4175 = 4175;\n            b.value4176 = 4176;\n            b.value4177 = 4177;\n            b.value4178 = 4178;\n            b.value4179 = 4179;\n            b.value4180 = 4180;\n            b.value4181 = 4181;\n            b.value4182 = 4182;\n            b.value4183 = 4183;\n            b.value4184 = 4184;\n            b.value4185 = 4185;\n            b.value4186 = 4186;\n            b.value4187 = 4187;\n            b.value4188 = 4188;\n            b.value4189 = 4189;\n            b.value4190 = 4190;\n            b.value4191 = 4191;\n            b.value4192 = 4192;\n            b.value4193 = 4193;\n            b.value4194 = 4194;\n            b.value4195 = 4195;\n            b.value4196 = 4196;\n            b.value4197 = 4197;\n            b.value4198 = 4198;\n            b.value4199 = 4199;\n            b.value4200 = 4200;\n            b.value4201 = 4201;\n            b.value4202 = 4202;\n            b.value4203 = 4203;\n            b.value4204 = 4204;\n            b.value4205 = 4205;\n            b.value4206 = 4206;\n            b.value4207 = 4207;\n            b.value4208 = 4208;\n            b.value4209 = 4209;\n            b.value4210 = 4210;\n            b.value4211 = 4211;\n            b.value4212 = 4212;\n            b.value4213 = 4213;\n            b.value4214 = 4214;\n            b.value4215 = 4215;\n            b.value4216 = 4216;\n            b.value4217 = 4217;\n            b.value4218 = 4218;\n            b.value4219 = 4219;\n            b.value4220 = 4220;\n            b.value4221 = 4221;\n            b.value4222 = 4222;\n            b.value4223 = 4223;\n            b.value4224 = 4224;\n            b.value4225 = 4225;\n            b.value4226 = 4226;\n            b.value4227 = 4227;\n            b.value4228 = 4228;\n            b.value4229 = 4229;\n            b.value4230 = 4230;\n            b.value4231 = 4231;\n            b.value4232 = 4232;\n            b.value4233 = 4233;\n            b.value4234 = 4234;\n            b.value4235 = 4235;\n            b.value4236 = 4236;\n            b.value4237 = 4237;\n            b.value4238 = 4238;\n            b.value4239 = 4239;\n            b.value4240 = 4240;\n            b.value4241 = 4241;\n            b.value4242 = 4242;\n            b.value4243 = 4243;\n            b.value4244 = 4244;\n            b.value4245 = 4245;\n            b.value4246 = 4246;\n            b.value4247 = 4247;\n            b.value4248 = 4248;\n            b.value4249 = 4249;\n            b.value4250 = 4250;\n            b.value4251 = 4251;\n            b.value4252 = 4252;\n            b.value4253 = 4253;\n            b.value4254 = 4254;\n            b.value4255 = 4255;\n            b.value4256 = 4256;\n            b.value4257 = 4257;\n            b.value4258 = 4258;\n            b.value4259 = 4259;\n            b.value4260 = 4260;\n            b.value4261 = 4261;\n            b.value4262 = 4262;\n            b.value4263 = 4263;\n            b.value4264 = 4264;\n            b.value4265 = 4265;\n            b.value4266 = 4266;\n            b.value4267 = 4267;\n            b.value4268 = 4268;\n            b.value4269 = 4269;\n            b.value4270 = 4270;\n            b.value4271 = 4271;\n            b.value4272 = 4272;\n            b.value4273 = 4273;\n            b.value4274 = 4274;\n            b.value4275 = 4275;\n            b.value4276 = 4276;\n            b.value4277 = 4277;\n            b.value4278 = 4278;\n            b.value4279 = 4279;\n            b.value4280 = 4280;\n            b.value4281 = 4281;\n            b.value4282 = 4282;\n            b.value4283 = 4283;\n            b.value4284 = 4284;\n            b.value4285 = 4285;\n            b.value4286 = 4286;\n            b.value4287 = 4287;\n            b.value4288 = 4288;\n            b.value4289 = 4289;\n            b.value4290 = 4290;\n            b.value4291 = 4291;\n            b.value4292 = 4292;\n            b.value4293 = 4293;\n            b.value4294 = 4294;\n            b.value4295 = 4295;\n            b.value4296 = 4296;\n            b.value4297 = 4297;\n            b.value4298 = 4298;\n            b.value4299 = 4299;\n            b.value4300 = 4300;\n            b.value4301 = 4301;\n            b.value4302 = 4302;\n            b.value4303 = 4303;\n            b.value4304 = 4304;\n            b.value4305 = 4305;\n            b.value4306 = 4306;\n            b.value4307 = 4307;\n            b.value4308 = 4308;\n            b.value4309 = 4309;\n            b.value4310 = 4310;\n            b.value4311 = 4311;\n            b.value4312 = 4312;\n            b.value4313 = 4313;\n            b.value4314 = 4314;\n            b.value4315 = 4315;\n            b.value4316 = 4316;\n            b.value4317 = 4317;\n            b.value4318 = 4318;\n            b.value4319 = 4319;\n            b.value4320 = 4320;\n            b.value4321 = 4321;\n            b.value4322 = 4322;\n            b.value4323 = 4323;\n            b.value4324 = 4324;\n            b.value4325 = 4325;\n            b.value4326 = 4326;\n            b.value4327 = 4327;\n            b.value4328 = 4328;\n            b.value4329 = 4329;\n            b.value4330 = 4330;\n            b.value4331 = 4331;\n            b.value4332 = 4332;\n            b.value4333 = 4333;\n            b.value4334 = 4334;\n            b.value4335 = 4335;\n            b.value4336 = 4336;\n            b.value4337 = 4337;\n            b.value4338 = 4338;\n            b.value4339 = 4339;\n            b.value4340 = 4340;\n            b.value4341 = 4341;\n            b.value4342 = 4342;\n            b.value4343 = 4343;\n            b.value4344 = 4344;\n            b.value4345 = 4345;\n            b.value4346 = 4346;\n            b.value4347 = 4347;\n            b.value4348 = 4348;\n            b.value4349 = 4349;\n            b.value4350 = 4350;\n            b.value4351 = 4351;\n            b.value4352 = 4352;\n            b.value4353 = 4353;\n            b.value4354 = 4354;\n            b.value4355 = 4355;\n            b.value4356 = 4356;\n            b.value4357 = 4357;\n            b.value4358 = 4358;\n            b.value4359 = 4359;\n            b.value4360 = 4360;\n            b.value4361 = 4361;\n            b.value4362 = 4362;\n            b.value4363 = 4363;\n            b.value4364 = 4364;\n            b.value4365 = 4365;\n            b.value4366 = 4366;\n            b.value4367 = 4367;\n            b.value4368 = 4368;\n            b.value4369 = 4369;\n            b.value4370 = 4370;\n            b.value4371 = 4371;\n            b.value4372 = 4372;\n            b.value4373 = 4373;\n            b.value4374 = 4374;\n            b.value4375 = 4375;\n            b.value4376 = 4376;\n            b.value4377 = 4377;\n            b.value4378 = 4378;\n            b.value4379 = 4379;\n            b.value4380 = 4380;\n            b.value4381 = 4381;\n            b.value4382 = 4382;\n            b.value4383 = 4383;\n            b.value4384 = 4384;\n            b.value4385 = 4385;\n            b.value4386 = 4386;\n            b.value4387 = 4387;\n            b.value4388 = 4388;\n            b.value4389 = 4389;\n            b.value4390 = 4390;\n            b.value4391 = 4391;\n            b.value4392 = 4392;\n            b.value4393 = 4393;\n            b.value4394 = 4394;\n            b.value4395 = 4395;\n            b.value4396 = 4396;\n            b.value4397 = 4397;\n            b.value4398 = 4398;\n            b.value4399 = 4399;\n            b.value4400 = 4400;\n            b.value4401 = 4401;\n            b.value4402 = 4402;\n            b.value4403 = 4403;\n            b.value4404 = 4404;\n            b.value4405 = 4405;\n            b.value4406 = 4406;\n            b.value4407 = 4407;\n            b.value4408 = 4408;\n            b.value4409 = 4409;\n            b.value4410 = 4410;\n            b.value4411 = 4411;\n            b.value4412 = 4412;\n            b.value4413 = 4413;\n            b.value4414 = 4414;\n            b.value4415 = 4415;\n            b.value4416 = 4416;\n            b.value4417 = 4417;\n            b.value4418 = 4418;\n            b.value4419 = 4419;\n            b.value4420 = 4420;\n            b.value4421 = 4421;\n            b.value4422 = 4422;\n            b.value4423 = 4423;\n            b.value4424 = 4424;\n            b.value4425 = 4425;\n            b.value4426 = 4426;\n            b.value4427 = 4427;\n            b.value4428 = 4428;\n            b.value4429 = 4429;\n            b.value4430 = 4430;\n            b.value4431 = 4431;\n            b.value4432 = 4432;\n            b.value4433 = 4433;\n            b.value4434 = 4434;\n            b.value4435 = 4435;\n            b.value4436 = 4436;\n            b.value4437 = 4437;\n            b.value4438 = 4438;\n            b.value4439 = 4439;\n            b.value4440 = 4440;\n            b.value4441 = 4441;\n            b.value4442 = 4442;\n            b.value4443 = 4443;\n            b.value4444 = 4444;\n            b.value4445 = 4445;\n            b.value4446 = 4446;\n            b.value4447 = 4447;\n            b.value4448 = 4448;\n            b.value4449 = 4449;\n            b.value4450 = 4450;\n            b.value4451 = 4451;\n            b.value4452 = 4452;\n            b.value4453 = 4453;\n            b.value4454 = 4454;\n            b.value4455 = 4455;\n            b.value4456 = 4456;\n            b.value4457 = 4457;\n            b.value4458 = 4458;\n            b.value4459 = 4459;\n            b.value4460 = 4460;\n            b.value4461 = 4461;\n            b.value4462 = 4462;\n            b.value4463 = 4463;\n            b.value4464 = 4464;\n            b.value4465 = 4465;\n            b.value4466 = 4466;\n            b.value4467 = 4467;\n            b.value4468 = 4468;\n            b.value4469 = 4469;\n            b.value4470 = 4470;\n            b.value4471 = 4471;\n            b.value4472 = 4472;\n            b.value4473 = 4473;\n            b.value4474 = 4474;\n            b.value4475 = 4475;\n            b.value4476 = 4476;\n            b.value4477 = 4477;\n            b.value4478 = 4478;\n            b.value4479 = 4479;\n            b.value4480 = 4480;\n            b.value4481 = 4481;\n            b.value4482 = 4482;\n            b.value4483 = 4483;\n            b.value4484 = 4484;\n            b.value4485 = 4485;\n            b.value4486 = 4486;\n            b.value4487 = 4487;\n            b.value4488 = 4488;\n            b.value4489 = 4489;\n            b.value4490 = 4490;\n            b.value4491 = 4491;\n            b.value4492 = 4492;\n            b.value4493 = 4493;\n            b.value4494 = 4494;\n            b.value4495 = 4495;\n            b.value4496 = 4496;\n            b.value4497 = 4497;\n            b.value4498 = 4498;\n            b.value4499 = 4499;\n            b.value4500 = 4500;\n            b.value4501 = 4501;\n            b.value4502 = 4502;\n            b.value4503 = 4503;\n            b.value4504 = 4504;\n            b.value4505 = 4505;\n            b.value4506 = 4506;\n            b.value4507 = 4507;\n            b.value4508 = 4508;\n            b.value4509 = 4509;\n            b.value4510 = 4510;\n            b.value4511 = 4511;\n            b.value4512 = 4512;\n            b.value4513 = 4513;\n            b.value4514 = 4514;\n            b.value4515 = 4515;\n            b.value4516 = 4516;\n            b.value4517 = 4517;\n            b.value4518 = 4518;\n            b.value4519 = 4519;\n            b.value4520 = 4520;\n            b.value4521 = 4521;\n            b.value4522 = 4522;\n            b.value4523 = 4523;\n            b.value4524 = 4524;\n            b.value4525 = 4525;\n            b.value4526 = 4526;\n            b.value4527 = 4527;\n            b.value4528 = 4528;\n            b.value4529 = 4529;\n            b.value4530 = 4530;\n            b.value4531 = 4531;\n            b.value4532 = 4532;\n            b.value4533 = 4533;\n            b.value4534 = 4534;\n            b.value4535 = 4535;\n            b.value4536 = 4536;\n            b.value4537 = 4537;\n            b.value4538 = 4538;\n            b.value4539 = 4539;\n            b.value4540 = 4540;\n            b.value4541 = 4541;\n            b.value4542 = 4542;\n            b.value4543 = 4543;\n            b.value4544 = 4544;\n            b.value4545 = 4545;\n            b.value4546 = 4546;\n            b.value4547 = 4547;\n            b.value4548 = 4548;\n            b.value4549 = 4549;\n            b.value4550 = 4550;\n            b.value4551 = 4551;\n            b.value4552 = 4552;\n            b.value4553 = 4553;\n            b.value4554 = 4554;\n            b.value4555 = 4555;\n            b.value4556 = 4556;\n            b.value4557 = 4557;\n            b.value4558 = 4558;\n            b.value4559 = 4559;\n            b.value4560 = 4560;\n            b.value4561 = 4561;\n            b.value4562 = 4562;\n            b.value4563 = 4563;\n            b.value4564 = 4564;\n            b.value4565 = 4565;\n            b.value4566 = 4566;\n            b.value4567 = 4567;\n            b.value4568 = 4568;\n            b.value4569 = 4569;\n            b.value4570 = 4570;\n            b.value4571 = 4571;\n            b.value4572 = 4572;\n            b.value4573 = 4573;\n            b.value4574 = 4574;\n            b.value4575 = 4575;\n            b.value4576 = 4576;\n            b.value4577 = 4577;\n            b.value4578 = 4578;\n            b.value4579 = 4579;\n            b.value4580 = 4580;\n            b.value4581 = 4581;\n            b.value4582 = 4582;\n            b.value4583 = 4583;\n            b.value4584 = 4584;\n            b.value4585 = 4585;\n            b.value4586 = 4586;\n            b.value4587 = 4587;\n            b.value4588 = 4588;\n            b.value4589 = 4589;\n            b.value4590 = 4590;\n            b.value4591 = 4591;\n            b.value4592 = 4592;\n            b.value4593 = 4593;\n            b.value4594 = 4594;\n            b.value4595 = 4595;\n            b.value4596 = 4596;\n            b.value4597 = 4597;\n            b.value4598 = 4598;\n            b.value4599 = 4599;\n            b.value4600 = 4600;\n            b.value4601 = 4601;\n            b.value4602 = 4602;\n            b.value4603 = 4603;\n            b.value4604 = 4604;\n            b.value4605 = 4605;\n            b.value4606 = 4606;\n            b.value4607 = 4607;\n            b.value4608 = 4608;\n            b.value4609 = 4609;\n            b.value4610 = 4610;\n            b.value4611 = 4611;\n            b.value4612 = 4612;\n            b.value4613 = 4613;\n            b.value4614 = 4614;\n            b.value4615 = 4615;\n            b.value4616 = 4616;\n            b.value4617 = 4617;\n            b.value4618 = 4618;\n            b.value4619 = 4619;\n            b.value4620 = 4620;\n            b.value4621 = 4621;\n            b.value4622 = 4622;\n            b.value4623 = 4623;\n            b.value4624 = 4624;\n            b.value4625 = 4625;\n            b.value4626 = 4626;\n            b.value4627 = 4627;\n            b.value4628 = 4628;\n            b.value4629 = 4629;\n            b.value4630 = 4630;\n            b.value4631 = 4631;\n            b.value4632 = 4632;\n            b.value4633 = 4633;\n            b.value4634 = 4634;\n            b.value4635 = 4635;\n            b.value4636 = 4636;\n            b.value4637 = 4637;\n            b.value4638 = 4638;\n            b.value4639 = 4639;\n            b.value4640 = 4640;\n            b.value4641 = 4641;\n            b.value4642 = 4642;\n            b.value4643 = 4643;\n            b.value4644 = 4644;\n            b.value4645 = 4645;\n            b.value4646 = 4646;\n            b.value4647 = 4647;\n            b.value4648 = 4648;\n            b.value4649 = 4649;\n            b.value4650 = 4650;\n            b.value4651 = 4651;\n            b.value4652 = 4652;\n            b.value4653 = 4653;\n            b.value4654 = 4654;\n            b.value4655 = 4655;\n            b.value4656 = 4656;\n            b.value4657 = 4657;\n            b.value4658 = 4658;\n            b.value4659 = 4659;\n            b.value4660 = 4660;\n            b.value4661 = 4661;\n            b.value4662 = 4662;\n            b.value4663 = 4663;\n            b.value4664 = 4664;\n            b.value4665 = 4665;\n            b.value4666 = 4666;\n            b.value4667 = 4667;\n            b.value4668 = 4668;\n            b.value4669 = 4669;\n            b.value4670 = 4670;\n            b.value4671 = 4671;\n            b.value4672 = 4672;\n            b.value4673 = 4673;\n            b.value4674 = 4674;\n            b.value4675 = 4675;\n            b.value4676 = 4676;\n            b.value4677 = 4677;\n            b.value4678 = 4678;\n            b.value4679 = 4679;\n            b.value4680 = 4680;\n            b.value4681 = 4681;\n            b.value4682 = 4682;\n            b.value4683 = 4683;\n            b.value4684 = 4684;\n            b.value4685 = 4685;\n            b.value4686 = 4686;\n            b.value4687 = 4687;\n            b.value4688 = 4688;\n            b.value4689 = 4689;\n            b.value4690 = 4690;\n            b.value4691 = 4691;\n            b.value4692 = 4692;\n            b.value4693 = 4693;\n            b.value4694 = 4694;\n            b.value4695 = 4695;\n            b.value4696 = 4696;\n            b.value4697 = 4697;\n            b.value4698 = 4698;\n            b.value4699 = 4699;\n            b.value4700 = 4700;\n            b.value4701 = 4701;\n            b.value4702 = 4702;\n            b.value4703 = 4703;\n            b.value4704 = 4704;\n            b.value4705 = 4705;\n            b.value4706 = 4706;\n            b.value4707 = 4707;\n            b.value4708 = 4708;\n            b.value4709 = 4709;\n            b.value4710 = 4710;\n            b.value4711 = 4711;\n            b.value4712 = 4712;\n            b.value4713 = 4713;\n            b.value4714 = 4714;\n            b.value4715 = 4715;\n            b.value4716 = 4716;\n            b.value4717 = 4717;\n            b.value4718 = 4718;\n            b.value4719 = 4719;\n            b.value4720 = 4720;\n            b.value4721 = 4721;\n            b.value4722 = 4722;\n            b.value4723 = 4723;\n            b.value4724 = 4724;\n            b.value4725 = 4725;\n            b.value4726 = 4726;\n            b.value4727 = 4727;\n            b.value4728 = 4728;\n            b.value4729 = 4729;\n            b.value4730 = 4730;\n            b.value4731 = 4731;\n            b.value4732 = 4732;\n            b.value4733 = 4733;\n            b.value4734 = 4734;\n            b.value4735 = 4735;\n            b.value4736 = 4736;\n            b.value4737 = 4737;\n            b.value4738 = 4738;\n            b.value4739 = 4739;\n            b.value4740 = 4740;\n            b.value4741 = 4741;\n            b.value4742 = 4742;\n            b.value4743 = 4743;\n            b.value4744 = 4744;\n            b.value4745 = 4745;\n            b.value4746 = 4746;\n            b.value4747 = 4747;\n            b.value4748 = 4748;\n            b.value4749 = 4749;\n            b.value4750 = 4750;\n            b.value4751 = 4751;\n            b.value4752 = 4752;\n            b.value4753 = 4753;\n            b.value4754 = 4754;\n            b.value4755 = 4755;\n            b.value4756 = 4756;\n            b.value4757 = 4757;\n            b.value4758 = 4758;\n            b.value4759 = 4759;\n            b.value4760 = 4760;\n            b.value4761 = 4761;\n            b.value4762 = 4762;\n            b.value4763 = 4763;\n            b.value4764 = 4764;\n            b.value4765 = 4765;\n            b.value4766 = 4766;\n            b.value4767 = 4767;\n            b.value4768 = 4768;\n            b.value4769 = 4769;\n            b.value4770 = 4770;\n            b.value4771 = 4771;\n            b.value4772 = 4772;\n            b.value4773 = 4773;\n            b.value4774 = 4774;\n            b.value4775 = 4775;\n            b.value4776 = 4776;\n            b.value4777 = 4777;\n            b.value4778 = 4778;\n            b.value4779 = 4779;\n            b.value4780 = 4780;\n            b.value4781 = 4781;\n            b.value4782 = 4782;\n            b.value4783 = 4783;\n            b.value4784 = 4784;\n            b.value4785 = 4785;\n            b.value4786 = 4786;\n            b.value4787 = 4787;\n            b.value4788 = 4788;\n            b.value4789 = 4789;\n            b.value4790 = 4790;\n            b.value4791 = 4791;\n            b.value4792 = 4792;\n            b.value4793 = 4793;\n            b.value4794 = 4794;\n            b.value4795 = 4795;\n            b.value4796 = 4796;\n            b.value4797 = 4797;\n            b.value4798 = 4798;\n            b.value4799 = 4799;\n            b.value4800 = 4800;\n            b.value4801 = 4801;\n            b.value4802 = 4802;\n            b.value4803 = 4803;\n            b.value4804 = 4804;\n            b.value4805 = 4805;\n            b.value4806 = 4806;\n            b.value4807 = 4807;\n            b.value4808 = 4808;\n            b.value4809 = 4809;\n            b.value4810 = 4810;\n            b.value4811 = 4811;\n            b.value4812 = 4812;\n            b.value4813 = 4813;\n            b.value4814 = 4814;\n            b.value4815 = 4815;\n            b.value4816 = 4816;\n            b.value4817 = 4817;\n            b.value4818 = 4818;\n            b.value4819 = 4819;\n            b.value4820 = 4820;\n            b.value4821 = 4821;\n            b.value4822 = 4822;\n            b.value4823 = 4823;\n            b.value4824 = 4824;\n            b.value4825 = 4825;\n            b.value4826 = 4826;\n            b.value4827 = 4827;\n            b.value4828 = 4828;\n            b.value4829 = 4829;\n            b.value4830 = 4830;\n            b.value4831 = 4831;\n            b.value4832 = 4832;\n            b.value4833 = 4833;\n            b.value4834 = 4834;\n            b.value4835 = 4835;\n            b.value4836 = 4836;\n            b.value4837 = 4837;\n            b.value4838 = 4838;\n            b.value4839 = 4839;\n            b.value4840 = 4840;\n            b.value4841 = 4841;\n            b.value4842 = 4842;\n            b.value4843 = 4843;\n            b.value4844 = 4844;\n            b.value4845 = 4845;\n            b.value4846 = 4846;\n            b.value4847 = 4847;\n            b.value4848 = 4848;\n            b.value4849 = 4849;\n            b.value4850 = 4850;\n            b.value4851 = 4851;\n            b.value4852 = 4852;\n            b.value4853 = 4853;\n            b.value4854 = 4854;\n            b.value4855 = 4855;\n            b.value4856 = 4856;\n            b.value4857 = 4857;\n            b.value4858 = 4858;\n            b.value4859 = 4859;\n            b.value4860 = 4860;\n            b.value4861 = 4861;\n            b.value4862 = 4862;\n            b.value4863 = 4863;\n            b.value4864 = 4864;\n            b.value4865 = 4865;\n            b.value4866 = 4866;\n            b.value4867 = 4867;\n            b.value4868 = 4868;\n            b.value4869 = 4869;\n            b.value4870 = 4870;\n            b.value4871 = 4871;\n            b.value4872 = 4872;\n            b.value4873 = 4873;\n            b.value4874 = 4874;\n            b.value4875 = 4875;\n            b.value4876 = 4876;\n            b.value4877 = 4877;\n            b.value4878 = 4878;\n            b.value4879 = 4879;\n            b.value4880 = 4880;\n            b.value4881 = 4881;\n            b.value4882 = 4882;\n            b.value4883 = 4883;\n            b.value4884 = 4884;\n            b.value4885 = 4885;\n            b.value4886 = 4886;\n            b.value4887 = 4887;\n            b.value4888 = 4888;\n            b.value4889 = 4889;\n            b.value4890 = 4890;\n            b.value4891 = 4891;\n            b.value4892 = 4892;\n            b.value4893 = 4893;\n            b.value4894 = 4894;\n            b.value4895 = 4895;\n            b.value4896 = 4896;\n            b.value4897 = 4897;\n            b.value4898 = 4898;\n            b.value4899 = 4899;\n            b.value4900 = 4900;\n            b.value4901 = 4901;\n            b.value4902 = 4902;\n            b.value4903 = 4903;\n            b.value4904 = 4904;\n            b.value4905 = 4905;\n            b.value4906 = 4906;\n            b.value4907 = 4907;\n            b.value4908 = 4908;\n            b.value4909 = 4909;\n            b.value4910 = 4910;\n            b.value4911 = 4911;\n            b.value4912 = 4912;\n            b.value4913 = 4913;\n            b.value4914 = 4914;\n            b.value4915 = 4915;\n            b.value4916 = 4916;\n            b.value4917 = 4917;\n            b.value4918 = 4918;\n            b.value4919 = 4919;\n            b.value4920 = 4920;\n            b.value4921 = 4921;\n            b.value4922 = 4922;\n            b.value4923 = 4923;\n            b.value4924 = 4924;\n            b.value4925 = 4925;\n            b.value4926 = 4926;\n            b.value4927 = 4927;\n            b.value4928 = 4928;\n            b.value4929 = 4929;\n            b.value4930 = 4930;\n            b.value4931 = 4931;\n            b.value4932 = 4932;\n            b.value4933 = 4933;\n            b.value4934 = 4934;\n            b.value4935 = 4935;\n            b.value4936 = 4936;\n            b.value4937 = 4937;\n            b.value4938 = 4938;\n            b.value4939 = 4939;\n            b.value4940 = 4940;\n            b.value4941 = 4941;\n            b.value4942 = 4942;\n            b.value4943 = 4943;\n            b.value4944 = 4944;\n            b.value4945 = 4945;\n            b.value4946 = 4946;\n            b.value4947 = 4947;\n            b.value4948 = 4948;\n            b.value4949 = 4949;\n            b.value4950 = 4950;\n            b.value4951 = 4951;\n            b.value4952 = 4952;\n            b.value4953 = 4953;\n            b.value4954 = 4954;\n            b.value4955 = 4955;\n            b.value4956 = 4956;\n            b.value4957 = 4957;\n            b.value4958 = 4958;\n            b.value4959 = 4959;\n            b.value4960 = 4960;\n            b.value4961 = 4961;\n            b.value4962 = 4962;\n            b.value4963 = 4963;\n            b.value4964 = 4964;\n            b.value4965 = 4965;\n            b.value4966 = 4966;\n            b.value4967 = 4967;\n            b.value4968 = 4968;\n            b.value4969 = 4969;\n            b.value4970 = 4970;\n            b.value4971 = 4971;\n            b.value4972 = 4972;\n            b.value4973 = 4973;\n            b.value4974 = 4974;\n            b.value4975 = 4975;\n            b.value4976 = 4976;\n            b.value4977 = 4977;\n            b.value4978 = 4978;\n            b.value4979 = 4979;\n            b.value4980 = 4980;\n            b.value4981 = 4981;\n            b.value4982 = 4982;\n            b.value4983 = 4983;\n            b.value4984 = 4984;\n            b.value4985 = 4985;\n            b.value4986 = 4986;\n            b.value4987 = 4987;\n            b.value4988 = 4988;\n            b.value4989 = 4989;\n            b.value4990 = 4990;\n            b.value4991 = 4991;\n            b.value4992 = 4992;\n            b.value4993 = 4993;\n            b.value4994 = 4994;\n            b.value4995 = 4995;\n            b.value4996 = 4996;\n            b.value4997 = 4997;\n            b.value4998 = 4998;\n            b.value4999 = 4999;\n            b.value5000 = 5000;\n            b.value5001 = 5001;\n            b.value5002 = 5002;\n            b.value5003 = 5003;\n            b.value5004 = 5004;\n            b.value5005 = 5005;\n            b.value5006 = 5006;\n            b.value5007 = 5007;\n            b.value5008 = 5008;\n            b.value5009 = 5009;\n            b.value5010 = 5010;\n            b.value5011 = 5011;\n            b.value5012 = 5012;\n            b.value5013 = 5013;\n            b.value5014 = 5014;\n            b.value5015 = 5015;\n            b.value5016 = 5016;\n            b.value5017 = 5017;\n            b.value5018 = 5018;\n            b.value5019 = 5019;\n            b.value5020 = 5020;\n            b.value5021 = 5021;\n            b.value5022 = 5022;\n            b.value5023 = 5023;\n            b.value5024 = 5024;\n            b.value5025 = 5025;\n            b.value5026 = 5026;\n            b.value5027 = 5027;\n            b.value5028 = 5028;\n            b.value5029 = 5029;\n            b.value5030 = 5030;\n            b.value5031 = 5031;\n            b.value5032 = 5032;\n            b.value5033 = 5033;\n            b.value5034 = 5034;\n            b.value5035 = 5035;\n            b.value5036 = 5036;\n            b.value5037 = 5037;\n            b.value5038 = 5038;\n            b.value5039 = 5039;\n            b.value5040 = 5040;\n            b.value5041 = 5041;\n            b.value5042 = 5042;\n            b.value5043 = 5043;\n            b.value5044 = 5044;\n            b.value5045 = 5045;\n            b.value5046 = 5046;\n            b.value5047 = 5047;\n            b.value5048 = 5048;\n            b.value5049 = 5049;\n            b.value5050 = 5050;\n            b.value5051 = 5051;\n            b.value5052 = 5052;\n            b.value5053 = 5053;\n            b.value5054 = 5054;\n            b.value5055 = 5055;\n            b.value5056 = 5056;\n            b.value5057 = 5057;\n            b.value5058 = 5058;\n            b.value5059 = 5059;\n            b.value5060 = 5060;\n            b.value5061 = 5061;\n            b.value5062 = 5062;\n            b.value5063 = 5063;\n            b.value5064 = 5064;\n            b.value5065 = 5065;\n            b.value5066 = 5066;\n            b.value5067 = 5067;\n            b.value5068 = 5068;\n            b.value5069 = 5069;\n            b.value5070 = 5070;\n            b.value5071 = 5071;\n            b.value5072 = 5072;\n            b.value5073 = 5073;\n            b.value5074 = 5074;\n            b.value5075 = 5075;\n            b.value5076 = 5076;\n            b.value5077 = 5077;\n            b.value5078 = 5078;\n            b.value5079 = 5079;\n            b.value5080 = 5080;\n            b.value5081 = 5081;\n            b.value5082 = 5082;\n            b.value5083 = 5083;\n            b.value5084 = 5084;\n            b.value5085 = 5085;\n            b.value5086 = 5086;\n            b.value5087 = 5087;\n            b.value5088 = 5088;\n            b.value5089 = 5089;\n            b.value5090 = 5090;\n            b.value5091 = 5091;\n            b.value5092 = 5092;\n            b.value5093 = 5093;\n            b.value5094 = 5094;\n            b.value5095 = 5095;\n            b.value5096 = 5096;\n            b.value5097 = 5097;\n            b.value5098 = 5098;\n            b.value5099 = 5099;\n            b.value5100 = 5100;\n            b.value5101 = 5101;\n            b.value5102 = 5102;\n            b.value5103 = 5103;\n            b.value5104 = 5104;\n            b.value5105 = 5105;\n            b.value5106 = 5106;\n            b.value5107 = 5107;\n            b.value5108 = 5108;\n            b.value5109 = 5109;\n            b.value5110 = 5110;\n            b.value5111 = 5111;\n            b.value5112 = 5112;\n            b.value5113 = 5113;\n            b.value5114 = 5114;\n            b.value5115 = 5115;\n            b.value5116 = 5116;\n            b.value5117 = 5117;\n            b.value5118 = 5118;\n            b.value5119 = 5119;\n            b.value5120 = 5120;\n            b.value5121 = 5121;\n            b.value5122 = 5122;\n            b.value5123 = 5123;\n            b.value5124 = 5124;\n            b.value5125 = 5125;\n            b.value5126 = 5126;\n            b.value5127 = 5127;\n            b.value5128 = 5128;\n            b.value5129 = 5129;\n            b.value5130 = 5130;\n            b.value5131 = 5131;\n            b.value5132 = 5132;\n            b.value5133 = 5133;\n            b.value5134 = 5134;\n            b.value5135 = 5135;\n            b.value5136 = 5136;\n            b.value5137 = 5137;\n            b.value5138 = 5138;\n            b.value5139 = 5139;\n            b.value5140 = 5140;\n            b.value5141 = 5141;\n            b.value5142 = 5142;\n            b.value5143 = 5143;\n            b.value5144 = 5144;\n            b.value5145 = 5145;\n            b.value5146 = 5146;\n            b.value5147 = 5147;\n            b.value5148 = 5148;\n            b.value5149 = 5149;\n            b.value5150 = 5150;\n            b.value5151 = 5151;\n            b.value5152 = 5152;\n            b.value5153 = 5153;\n            b.value5154 = 5154;\n            b.value5155 = 5155;\n            b.value5156 = 5156;\n            b.value5157 = 5157;\n            b.value5158 = 5158;\n            b.value5159 = 5159;\n            b.value5160 = 5160;\n            b.value5161 = 5161;\n            b.value5162 = 5162;\n            b.value5163 = 5163;\n            b.value5164 = 5164;\n            b.value5165 = 5165;\n            b.value5166 = 5166;\n            b.value5167 = 5167;\n            b.value5168 = 5168;\n            b.value5169 = 5169;\n            b.value5170 = 5170;\n            b.value5171 = 5171;\n            b.value5172 = 5172;\n            b.value5173 = 5173;\n            b.value5174 = 5174;\n            b.value5175 = 5175;\n            b.value5176 = 5176;\n            b.value5177 = 5177;\n            b.value5178 = 5178;\n            b.value5179 = 5179;\n            b.value5180 = 5180;\n            b.value5181 = 5181;\n            b.value5182 = 5182;\n            b.value5183 = 5183;\n            b.value5184 = 5184;\n            b.value5185 = 5185;\n            b.value5186 = 5186;\n            b.value5187 = 5187;\n            b.value5188 = 5188;\n            b.value5189 = 5189;\n            b.value5190 = 5190;\n            b.value5191 = 5191;\n            b.value5192 = 5192;\n            b.value5193 = 5193;\n            b.value5194 = 5194;\n            b.value5195 = 5195;\n            b.value5196 = 5196;\n            b.value5197 = 5197;\n            b.value5198 = 5198;\n            b.value5199 = 5199;\n            b.value5200 = 5200;\n            b.value5201 = 5201;\n            b.value5202 = 5202;\n            b.value5203 = 5203;\n            b.value5204 = 5204;\n            b.value5205 = 5205;\n            b.value5206 = 5206;\n            b.value5207 = 5207;\n            b.value5208 = 5208;\n            b.value5209 = 5209;\n            b.value5210 = 5210;\n            b.value5211 = 5211;\n            b.value5212 = 5212;\n            b.value5213 = 5213;\n            b.value5214 = 5214;\n            b.value5215 = 5215;\n            b.value5216 = 5216;\n            b.value5217 = 5217;\n            b.value5218 = 5218;\n            b.value5219 = 5219;\n            b.value5220 = 5220;\n            b.value5221 = 5221;\n            b.value5222 = 5222;\n            b.value5223 = 5223;\n            b.value5224 = 5224;\n            b.value5225 = 5225;\n            b.value5226 = 5226;\n            b.value5227 = 5227;\n            b.value5228 = 5228;\n            b.value5229 = 5229;\n            b.value5230 = 5230;\n            b.value5231 = 5231;\n            b.value5232 = 5232;\n            b.value5233 = 5233;\n            b.value5234 = 5234;\n            b.value5235 = 5235;\n            b.value5236 = 5236;\n            b.value5237 = 5237;\n            b.value5238 = 5238;\n            b.value5239 = 5239;\n            b.value5240 = 5240;\n            b.value5241 = 5241;\n            b.value5242 = 5242;\n            b.value5243 = 5243;\n            b.value5244 = 5244;\n            b.value5245 = 5245;\n            b.value5246 = 5246;\n            b.value5247 = 5247;\n            b.value5248 = 5248;\n            b.value5249 = 5249;\n            b.value5250 = 5250;\n            b.value5251 = 5251;\n            b.value5252 = 5252;\n            b.value5253 = 5253;\n            b.value5254 = 5254;\n            b.value5255 = 5255;\n            b.value5256 = 5256;\n            b.value5257 = 5257;\n            b.value5258 = 5258;\n            b.value5259 = 5259;\n            b.value5260 = 5260;\n            b.value5261 = 5261;\n            b.value5262 = 5262;\n            b.value5263 = 5263;\n            b.value5264 = 5264;\n            b.value5265 = 5265;\n            b.value5266 = 5266;\n            b.value5267 = 5267;\n            b.value5268 = 5268;\n            b.value5269 = 5269;\n            b.value5270 = 5270;\n            b.value5271 = 5271;\n            b.value5272 = 5272;\n            b.value5273 = 5273;\n            b.value5274 = 5274;\n            b.value5275 = 5275;\n            b.value5276 = 5276;\n            b.value5277 = 5277;\n            b.value5278 = 5278;\n            b.value5279 = 5279;\n            b.value5280 = 5280;\n            b.value5281 = 5281;\n            b.value5282 = 5282;\n            b.value5283 = 5283;\n            b.value5284 = 5284;\n            b.value5285 = 5285;\n            b.value5286 = 5286;\n            b.value5287 = 5287;\n            b.value5288 = 5288;\n            b.value5289 = 5289;\n            b.value5290 = 5290;\n            b.value5291 = 5291;\n            b.value5292 = 5292;\n            b.value5293 = 5293;\n            b.value5294 = 5294;\n            b.value5295 = 5295;\n            b.value5296 = 5296;\n            b.value5297 = 5297;\n            b.value5298 = 5298;\n            b.value5299 = 5299;\n            b.value5300 = 5300;\n            b.value5301 = 5301;\n            b.value5302 = 5302;\n            b.value5303 = 5303;\n            b.value5304 = 5304;\n            b.value5305 = 5305;\n            b.value5306 = 5306;\n            b.value5307 = 5307;\n            b.value5308 = 5308;\n            b.value5309 = 5309;\n            b.value5310 = 5310;\n            b.value5311 = 5311;\n            b.value5312 = 5312;\n            b.value5313 = 5313;\n            b.value5314 = 5314;\n            b.value5315 = 5315;\n            b.value5316 = 5316;\n            b.value5317 = 5317;\n            b.value5318 = 5318;\n            b.value5319 = 5319;\n            b.value5320 = 5320;\n            b.value5321 = 5321;\n            b.value5322 = 5322;\n            b.value5323 = 5323;\n            b.value5324 = 5324;\n            b.value5325 = 5325;\n            b.value5326 = 5326;\n            b.value5327 = 5327;\n            b.value5328 = 5328;\n            b.value5329 = 5329;\n            b.value5330 = 5330;\n            b.value5331 = 5331;\n            b.value5332 = 5332;\n            b.value5333 = 5333;\n            b.value5334 = 5334;\n            b.value5335 = 5335;\n            b.value5336 = 5336;\n            b.value5337 = 5337;\n            b.value5338 = 5338;\n            b.value5339 = 5339;\n            b.value5340 = 5340;\n            b.value5341 = 5341;\n            b.value5342 = 5342;\n            b.value5343 = 5343;\n            b.value5344 = 5344;\n            b.value5345 = 5345;\n            b.value5346 = 5346;\n            b.value5347 = 5347;\n            b.value5348 = 5348;\n            b.value5349 = 5349;\n            b.value5350 = 5350;\n            b.value5351 = 5351;\n            b.value5352 = 5352;\n            b.value5353 = 5353;\n            b.value5354 = 5354;\n            b.value5355 = 5355;\n            b.value5356 = 5356;\n            b.value5357 = 5357;\n            b.value5358 = 5358;\n            b.value5359 = 5359;\n            b.value5360 = 5360;\n            b.value5361 = 5361;\n            b.value5362 = 5362;\n            b.value5363 = 5363;\n            b.value5364 = 5364;\n            b.value5365 = 5365;\n            b.value5366 = 5366;\n            b.value5367 = 5367;\n            b.value5368 = 5368;\n            b.value5369 = 5369;\n            b.value5370 = 5370;\n            b.value5371 = 5371;\n            b.value5372 = 5372;\n            b.value5373 = 5373;\n            b.value5374 = 5374;\n            b.value5375 = 5375;\n            b.value5376 = 5376;\n            b.value5377 = 5377;\n            b.value5378 = 5378;\n            b.value5379 = 5379;\n            b.value5380 = 5380;\n            b.value5381 = 5381;\n            b.value5382 = 5382;\n            b.value5383 = 5383;\n            b.value5384 = 5384;\n            b.value5385 = 5385;\n            b.value5386 = 5386;\n            b.value5387 = 5387;\n            b.value5388 = 5388;\n            b.value5389 = 5389;\n            b.value5390 = 5390;\n            b.value5391 = 5391;\n            b.value5392 = 5392;\n            b.value5393 = 5393;\n            b.value5394 = 5394;\n            b.value5395 = 5395;\n            b.value5396 = 5396;\n            b.value5397 = 5397;\n            b.value5398 = 5398;\n            b.value5399 = 5399;\n            b.value5400 = 5400;\n            b.value5401 = 5401;\n            b.value5402 = 5402;\n            b.value5403 = 5403;\n            b.value5404 = 5404;\n            b.value5405 = 5405;\n            b.value5406 = 5406;\n            b.value5407 = 5407;\n            b.value5408 = 5408;\n            b.value5409 = 5409;\n            b.value5410 = 5410;\n            b.value5411 = 5411;\n            b.value5412 = 5412;\n            b.value5413 = 5413;\n            b.value5414 = 5414;\n            b.value5415 = 5415;\n            b.value5416 = 5416;\n            b.value5417 = 5417;\n            b.value5418 = 5418;\n            b.value5419 = 5419;\n            b.value5420 = 5420;\n            b.value5421 = 5421;\n            b.value5422 = 5422;\n            b.value5423 = 5423;\n            b.value5424 = 5424;\n            b.value5425 = 5425;\n            b.value5426 = 5426;\n            b.value5427 = 5427;\n            b.value5428 = 5428;\n            b.value5429 = 5429;\n            b.value5430 = 5430;\n            b.value5431 = 5431;\n            b.value5432 = 5432;\n            b.value5433 = 5433;\n            b.value5434 = 5434;\n            b.value5435 = 5435;\n            b.value5436 = 5436;\n            b.value5437 = 5437;\n            b.value5438 = 5438;\n            b.value5439 = 5439;\n            b.value5440 = 5440;\n            b.value5441 = 5441;\n            b.value5442 = 5442;\n            b.value5443 = 5443;\n            b.value5444 = 5444;\n            b.value5445 = 5445;\n            b.value5446 = 5446;\n            b.value5447 = 5447;\n            b.value5448 = 5448;\n            b.value5449 = 5449;\n            b.value5450 = 5450;\n            b.value5451 = 5451;\n            b.value5452 = 5452;\n            b.value5453 = 5453;\n            b.value5454 = 5454;\n            b.value5455 = 5455;\n            b.value5456 = 5456;\n            b.value5457 = 5457;\n            b.value5458 = 5458;\n            b.value5459 = 5459;\n            b.value5460 = 5460;\n            b.value5461 = 5461;\n            b.value5462 = 5462;\n            b.value5463 = 5463;\n            b.value5464 = 5464;\n            b.value5465 = 5465;\n            b.value5466 = 5466;\n            b.value5467 = 5467;\n            b.value5468 = 5468;\n            b.value5469 = 5469;\n            b.value5470 = 5470;\n            b.value5471 = 5471;\n            b.value5472 = 5472;\n            b.value5473 = 5473;\n            b.value5474 = 5474;\n            b.value5475 = 5475;\n            b.value5476 = 5476;\n            b.value5477 = 5477;\n            b.value5478 = 5478;\n            b.value5479 = 5479;\n            b.value5480 = 5480;\n            b.value5481 = 5481;\n            b.value5482 = 5482;\n            b.value5483 = 5483;\n            b.value5484 = 5484;\n            b.value5485 = 5485;\n            b.value5486 = 5486;\n            b.value5487 = 5487;\n            b.value5488 = 5488;\n            b.value5489 = 5489;\n            b.value5490 = 5490;\n            b.value5491 = 5491;\n            b.value5492 = 5492;\n            b.value5493 = 5493;\n            b.value5494 = 5494;\n            b.value5495 = 5495;\n            b.value5496 = 5496;\n            b.value5497 = 5497;\n            b.value5498 = 5498;\n            b.value5499 = 5499;\n            b.value5500 = 5500;\n            b.value5501 = 5501;\n            b.value5502 = 5502;\n            b.value5503 = 5503;\n            b.value5504 = 5504;\n            b.value5505 = 5505;\n            b.value5506 = 5506;\n            b.value5507 = 5507;\n            b.value5508 = 5508;\n            b.value5509 = 5509;\n            b.value5510 = 5510;\n            b.value5511 = 5511;\n            b.value5512 = 5512;\n            b.value5513 = 5513;\n            b.value5514 = 5514;\n            b.value5515 = 5515;\n            b.value5516 = 5516;\n            b.value5517 = 5517;\n            b.value5518 = 5518;\n            b.value5519 = 5519;\n            b.value5520 = 5520;\n            b.value5521 = 5521;\n            b.value5522 = 5522;\n            b.value5523 = 5523;\n            b.value5524 = 5524;\n            b.value5525 = 5525;\n            b.value5526 = 5526;\n            b.value5527 = 5527;\n            b.value5528 = 5528;\n            b.value5529 = 5529;\n            b.value5530 = 5530;\n            b.value5531 = 5531;\n            b.value5532 = 5532;\n            b.value5533 = 5533;\n            b.value5534 = 5534;\n            b.value5535 = 5535;\n            b.value5536 = 5536;\n            b.value5537 = 5537;\n            b.value5538 = 5538;\n            b.value5539 = 5539;\n            b.value5540 = 5540;\n            b.value5541 = 5541;\n            b.value5542 = 5542;\n            b.value5543 = 5543;\n            b.value5544 = 5544;\n            b.value5545 = 5545;\n            b.value5546 = 5546;\n            b.value5547 = 5547;\n            b.value5548 = 5548;\n            b.value5549 = 5549;\n            b.value5550 = 5550;\n            b.value5551 = 5551;\n            b.value5552 = 5552;\n            b.value5553 = 5553;\n            b.value5554 = 5554;\n            b.value5555 = 5555;\n            b.value5556 = 5556;\n            b.value5557 = 5557;\n            b.value5558 = 5558;\n            b.value5559 = 5559;\n            b.value5560 = 5560;\n            b.value5561 = 5561;\n            b.value5562 = 5562;\n            b.value5563 = 5563;\n            b.value5564 = 5564;\n            b.value5565 = 5565;\n            b.value5566 = 5566;\n            b.value5567 = 5567;\n            b.value5568 = 5568;\n            b.value5569 = 5569;\n            b.value5570 = 5570;\n            b.value5571 = 5571;\n            b.value5572 = 5572;\n            b.value5573 = 5573;\n            b.value5574 = 5574;\n            b.value5575 = 5575;\n            b.value5576 = 5576;\n            b.value5577 = 5577;\n            b.value5578 = 5578;\n            b.value5579 = 5579;\n            b.value5580 = 5580;\n            b.value5581 = 5581;\n            b.value5582 = 5582;\n            b.value5583 = 5583;\n            b.value5584 = 5584;\n            b.value5585 = 5585;\n            b.value5586 = 5586;\n            b.value5587 = 5587;\n            b.value5588 = 5588;\n            b.value5589 = 5589;\n            b.value5590 = 5590;\n            b.value5591 = 5591;\n            b.value5592 = 5592;\n            b.value5593 = 5593;\n            b.value5594 = 5594;\n            b.value5595 = 5595;\n            b.value5596 = 5596;\n            b.value5597 = 5597;\n            b.value5598 = 5598;\n            b.value5599 = 5599;\n            b.value5600 = 5600;\n            b.value5601 = 5601;\n            b.value5602 = 5602;\n            b.value5603 = 5603;\n            b.value5604 = 5604;\n            b.value5605 = 5605;\n            b.value5606 = 5606;\n            b.value5607 = 5607;\n            b.value5608 = 5608;\n            b.value5609 = 5609;\n            b.value5610 = 5610;\n            b.value5611 = 5611;\n            b.value5612 = 5612;\n            b.value5613 = 5613;\n            b.value5614 = 5614;\n            b.value5615 = 5615;\n            b.value5616 = 5616;\n            b.value5617 = 5617;\n            b.value5618 = 5618;\n            b.value5619 = 5619;\n            b.value5620 = 5620;\n            b.value5621 = 5621;\n            b.value5622 = 5622;\n            b.value5623 = 5623;\n            b.value5624 = 5624;\n            b.value5625 = 5625;\n            b.value5626 = 5626;\n            b.value5627 = 5627;\n            b.value5628 = 5628;\n            b.value5629 = 5629;\n            b.value5630 = 5630;\n            b.value5631 = 5631;\n            b.value5632 = 5632;\n            b.value5633 = 5633;\n            b.value5634 = 5634;\n            b.value5635 = 5635;\n            b.value5636 = 5636;\n            b.value5637 = 5637;\n            b.value5638 = 5638;\n            b.value5639 = 5639;\n            b.value5640 = 5640;\n            b.value5641 = 5641;\n            b.value5642 = 5642;\n            b.value5643 = 5643;\n            b.value5644 = 5644;\n            b.value5645 = 5645;\n            b.value5646 = 5646;\n            b.value5647 = 5647;\n            b.value5648 = 5648;\n            b.value5649 = 5649;\n            b.value5650 = 5650;\n            b.value5651 = 5651;\n            b.value5652 = 5652;\n            b.value5653 = 5653;\n            b.value5654 = 5654;\n            b.value5655 = 5655;\n            b.value5656 = 5656;\n            b.value5657 = 5657;\n            b.value5658 = 5658;\n            b.value5659 = 5659;\n            b.value5660 = 5660;\n            b.value5661 = 5661;\n            b.value5662 = 5662;\n            b.value5663 = 5663;\n            b.value5664 = 5664;\n            b.value5665 = 5665;\n            b.value5666 = 5666;\n            b.value5667 = 5667;\n            b.value5668 = 5668;\n            b.value5669 = 5669;\n            b.value5670 = 5670;\n            b.value5671 = 5671;\n            b.value5672 = 5672;\n            b.value5673 = 5673;\n            b.value5674 = 5674;\n            b.value5675 = 5675;\n            b.value5676 = 5676;\n            b.value5677 = 5677;\n            b.value5678 = 5678;\n            b.value5679 = 5679;\n            b.value5680 = 5680;\n            b.value5681 = 5681;\n            b.value5682 = 5682;\n            b.value5683 = 5683;\n            b.value5684 = 5684;\n            b.value5685 = 5685;\n            b.value5686 = 5686;\n            b.value5687 = 5687;\n            b.value5688 = 5688;\n            b.value5689 = 5689;\n            b.value5690 = 5690;\n            b.value5691 = 5691;\n            b.value5692 = 5692;\n            b.value5693 = 5693;\n            b.value5694 = 5694;\n            b.value5695 = 5695;\n            b.value5696 = 5696;\n            b.value5697 = 5697;\n            b.value5698 = 5698;\n            b.value5699 = 5699;\n            b.value5700 = 5700;\n            b.value5701 = 5701;\n            b.value5702 = 5702;\n            b.value5703 = 5703;\n            b.value5704 = 5704;\n            b.value5705 = 5705;\n            b.value5706 = 5706;\n            b.value5707 = 5707;\n            b.value5708 = 5708;\n            b.value5709 = 5709;\n            b.value5710 = 5710;\n            b.value5711 = 5711;\n            b.value5712 = 5712;\n            b.value5713 = 5713;\n            b.value5714 = 5714;\n            b.value5715 = 5715;\n            b.value5716 = 5716;\n            b.value5717 = 5717;\n            b.value5718 = 5718;\n            b.value5719 = 5719;\n            b.value5720 = 5720;\n            b.value5721 = 5721;\n            b.value5722 = 5722;\n            b.value5723 = 5723;\n            b.value5724 = 5724;\n            b.value5725 = 5725;\n            b.value5726 = 5726;\n            b.value5727 = 5727;\n            b.value5728 = 5728;\n            b.value5729 = 5729;\n            b.value5730 = 5730;\n            b.value5731 = 5731;\n            b.value5732 = 5732;\n            b.value5733 = 5733;\n            b.value5734 = 5734;\n            b.value5735 = 5735;\n            b.value5736 = 5736;\n            b.value5737 = 5737;\n            b.value5738 = 5738;\n            b.value5739 = 5739;\n            b.value5740 = 5740;\n            b.value5741 = 5741;\n            b.value5742 = 5742;\n            b.value5743 = 5743;\n            b.value5744 = 5744;\n            b.value5745 = 5745;\n            b.value5746 = 5746;\n            b.value5747 = 5747;\n            b.value5748 = 5748;\n            b.value5749 = 5749;\n            b.value5750 = 5750;\n            b.value5751 = 5751;\n            b.value5752 = 5752;\n            b.value5753 = 5753;\n            b.value5754 = 5754;\n            b.value5755 = 5755;\n            b.value5756 = 5756;\n            b.value5757 = 5757;\n            b.value5758 = 5758;\n            b.value5759 = 5759;\n            b.value5760 = 5760;\n            b.value5761 = 5761;\n            b.value5762 = 5762;\n            b.value5763 = 5763;\n            b.value5764 = 5764;\n            b.value5765 = 5765;\n            b.value5766 = 5766;\n            b.value5767 = 5767;\n            b.value5768 = 5768;\n            b.value5769 = 5769;\n            b.value5770 = 5770;\n            b.value5771 = 5771;\n            b.value5772 = 5772;\n            b.value5773 = 5773;\n            b.value5774 = 5774;\n            b.value5775 = 5775;\n            b.value5776 = 5776;\n            b.value5777 = 5777;\n            b.value5778 = 5778;\n            b.value5779 = 5779;\n            b.value5780 = 5780;\n            b.value5781 = 5781;\n            b.value5782 = 5782;\n            b.value5783 = 5783;\n            b.value5784 = 5784;\n            b.value5785 = 5785;\n            b.value5786 = 5786;\n            b.value5787 = 5787;\n            b.value5788 = 5788;\n            b.value5789 = 5789;\n            b.value5790 = 5790;\n            b.value5791 = 5791;\n            b.value5792 = 5792;\n            b.value5793 = 5793;\n            b.value5794 = 5794;\n            b.value5795 = 5795;\n            b.value5796 = 5796;\n            b.value5797 = 5797;\n            b.value5798 = 5798;\n            b.value5799 = 5799;\n            b.value5800 = 5800;\n            b.value5801 = 5801;\n            b.value5802 = 5802;\n            b.value5803 = 5803;\n            b.value5804 = 5804;\n            b.value5805 = 5805;\n            b.value5806 = 5806;\n            b.value5807 = 5807;\n            b.value5808 = 5808;\n            b.value5809 = 5809;\n            b.value5810 = 5810;\n            b.value5811 = 5811;\n            b.value5812 = 5812;\n            b.value5813 = 5813;\n            b.value5814 = 5814;\n            b.value5815 = 5815;\n            b.value5816 = 5816;\n            b.value5817 = 5817;\n            b.value5818 = 5818;\n            b.value5819 = 5819;\n            b.value5820 = 5820;\n            b.value5821 = 5821;\n            b.value5822 = 5822;\n            b.value5823 = 5823;\n            b.value5824 = 5824;\n            b.value5825 = 5825;\n            b.value5826 = 5826;\n            b.value5827 = 5827;\n            b.value5828 = 5828;\n            b.value5829 = 5829;\n            b.value5830 = 5830;\n            b.value5831 = 5831;\n            b.value5832 = 5832;\n            b.value5833 = 5833;\n            b.value5834 = 5834;\n            b.value5835 = 5835;\n            b.value5836 = 5836;\n            b.value5837 = 5837;\n            b.value5838 = 5838;\n            b.value5839 = 5839;\n            b.value5840 = 5840;\n            b.value5841 = 5841;\n            b.value5842 = 5842;\n            b.value5843 = 5843;\n            b.value5844 = 5844;\n            b.value5845 = 5845;\n            b.value5846 = 5846;\n            b.value5847 = 5847;\n            b.value5848 = 5848;\n            b.value5849 = 5849;\n            b.value5850 = 5850;\n            b.value5851 = 5851;\n            b.value5852 = 5852;\n            b.value5853 = 5853;\n            b.value5854 = 5854;\n            b.value5855 = 5855;\n            b.value5856 = 5856;\n            b.value5857 = 5857;\n            b.value5858 = 5858;\n            b.value5859 = 5859;\n            b.value5860 = 5860;\n            b.value5861 = 5861;\n            b.value5862 = 5862;\n            b.value5863 = 5863;\n            b.value5864 = 5864;\n            b.value5865 = 5865;\n            b.value5866 = 5866;\n            b.value5867 = 5867;\n            b.value5868 = 5868;\n            b.value5869 = 5869;\n            b.value5870 = 5870;\n            b.value5871 = 5871;\n            b.value5872 = 5872;\n            b.value5873 = 5873;\n            b.value5874 = 5874;\n            b.value5875 = 5875;\n            b.value5876 = 5876;\n            b.value5877 = 5877;\n            b.value5878 = 5878;\n            b.value5879 = 5879;\n            b.value5880 = 5880;\n            b.value5881 = 5881;\n            b.value5882 = 5882;\n            b.value5883 = 5883;\n            b.value5884 = 5884;\n            b.value5885 = 5885;\n            b.value5886 = 5886;\n            b.value5887 = 5887;\n            b.value5888 = 5888;\n            b.value5889 = 5889;\n            b.value5890 = 5890;\n            b.value5891 = 5891;\n            b.value5892 = 5892;\n            b.value5893 = 5893;\n            b.value5894 = 5894;\n            b.value5895 = 5895;\n            b.value5896 = 5896;\n            b.value5897 = 5897;\n            b.value5898 = 5898;\n            b.value5899 = 5899;\n            b.value5900 = 5900;\n            b.value5901 = 5901;\n            b.value5902 = 5902;\n            b.value5903 = 5903;\n            b.value5904 = 5904;\n            b.value5905 = 5905;\n            b.value5906 = 5906;\n            b.value5907 = 5907;\n            b.value5908 = 5908;\n            b.value5909 = 5909;\n            b.value5910 = 5910;\n            b.value5911 = 5911;\n            b.value5912 = 5912;\n            b.value5913 = 5913;\n            b.value5914 = 5914;\n            b.value5915 = 5915;\n            b.value5916 = 5916;\n            b.value5917 = 5917;\n            b.value5918 = 5918;\n            b.value5919 = 5919;\n            b.value5920 = 5920;\n            b.value5921 = 5921;\n            b.value5922 = 5922;\n            b.value5923 = 5923;\n            b.value5924 = 5924;\n            b.value5925 = 5925;\n            b.value5926 = 5926;\n            b.value5927 = 5927;\n            b.value5928 = 5928;\n            b.value5929 = 5929;\n            b.value5930 = 5930;\n            b.value5931 = 5931;\n            b.value5932 = 5932;\n            b.value5933 = 5933;\n            b.value5934 = 5934;\n            b.value5935 = 5935;\n            b.value5936 = 5936;\n            b.value5937 = 5937;\n            b.value5938 = 5938;\n            b.value5939 = 5939;\n            b.value5940 = 5940;\n            b.value5941 = 5941;\n            b.value5942 = 5942;\n            b.value5943 = 5943;\n            b.value5944 = 5944;\n            b.value5945 = 5945;\n            b.value5946 = 5946;\n            b.value5947 = 5947;\n            b.value5948 = 5948;\n            b.value5949 = 5949;\n            b.value5950 = 5950;\n            b.value5951 = 5951;\n            b.value5952 = 5952;\n            b.value5953 = 5953;\n            b.value5954 = 5954;\n            b.value5955 = 5955;\n            b.value5956 = 5956;\n            b.value5957 = 5957;\n            b.value5958 = 5958;\n            b.value5959 = 5959;\n            b.value5960 = 5960;\n            b.value5961 = 5961;\n            b.value5962 = 5962;\n            b.value5963 = 5963;\n            b.value5964 = 5964;\n            b.value5965 = 5965;\n            b.value5966 = 5966;\n            b.value5967 = 5967;\n            b.value5968 = 5968;\n            b.value5969 = 5969;\n            b.value5970 = 5970;\n            b.value5971 = 5971;\n            b.value5972 = 5972;\n            b.value5973 = 5973;\n            b.value5974 = 5974;\n            b.value5975 = 5975;\n            b.value5976 = 5976;\n            b.value5977 = 5977;\n            b.value5978 = 5978;\n            b.value5979 = 5979;\n            b.value5980 = 5980;\n            b.value5981 = 5981;\n            b.value5982 = 5982;\n            b.value5983 = 5983;\n            b.value5984 = 5984;\n            b.value5985 = 5985;\n            b.value5986 = 5986;\n            b.value5987 = 5987;\n            b.value5988 = 5988;\n            b.value5989 = 5989;\n            b.value5990 = 5990;\n            b.value5991 = 5991;\n            b.value5992 = 5992;\n            b.value5993 = 5993;\n            b.value5994 = 5994;\n            b.value5995 = 5995;\n            b.value5996 = 5996;\n            b.value5997 = 5997;\n            b.value5998 = 5998;\n            b.value5999 = 5999;\n            b.value6000 = 6000;\n            b.value6001 = 6001;\n            b.value6002 = 6002;\n            b.value6003 = 6003;\n            b.value6004 = 6004;\n            b.value6005 = 6005;\n            b.value6006 = 6006;\n            b.value6007 = 6007;\n            b.value6008 = 6008;\n            b.value6009 = 6009;\n            b.value6010 = 6010;\n            b.value6011 = 6011;\n            b.value6012 = 6012;\n            b.value6013 = 6013;\n            b.value6014 = 6014;\n            b.value6015 = 6015;\n            b.value6016 = 6016;\n            b.value6017 = 6017;\n            b.value6018 = 6018;\n            b.value6019 = 6019;\n            b.value6020 = 6020;\n            b.value6021 = 6021;\n            b.value6022 = 6022;\n            b.value6023 = 6023;\n            b.value6024 = 6024;\n            b.value6025 = 6025;\n            b.value6026 = 6026;\n            b.value6027 = 6027;\n            b.value6028 = 6028;\n            b.value6029 = 6029;\n            b.value6030 = 6030;\n            b.value6031 = 6031;\n            b.value6032 = 6032;\n            b.value6033 = 6033;\n            b.value6034 = 6034;\n            b.value6035 = 6035;\n            b.value6036 = 6036;\n            b.value6037 = 6037;\n            b.value6038 = 6038;\n            b.value6039 = 6039;\n            b.value6040 = 6040;\n            b.value6041 = 6041;\n            b.value6042 = 6042;\n            b.value6043 = 6043;\n            b.value6044 = 6044;\n            b.value6045 = 6045;\n            b.value6046 = 6046;\n            b.value6047 = 6047;\n            b.value6048 = 6048;\n            b.value6049 = 6049;\n            b.value6050 = 6050;\n            b.value6051 = 6051;\n            b.value6052 = 6052;\n            b.value6053 = 6053;\n            b.value6054 = 6054;\n            b.value6055 = 6055;\n            b.value6056 = 6056;\n            b.value6057 = 6057;\n            b.value6058 = 6058;\n            b.value6059 = 6059;\n            b.value6060 = 6060;\n            b.value6061 = 6061;\n            b.value6062 = 6062;\n            b.value6063 = 6063;\n            b.value6064 = 6064;\n            b.value6065 = 6065;\n            b.value6066 = 6066;\n            b.value6067 = 6067;\n            b.value6068 = 6068;\n            b.value6069 = 6069;\n            b.value6070 = 6070;\n            b.value6071 = 6071;\n            b.value6072 = 6072;\n            b.value6073 = 6073;\n            b.value6074 = 6074;\n            b.value6075 = 6075;\n            b.value6076 = 6076;\n            b.value6077 = 6077;\n            b.value6078 = 6078;\n            b.value6079 = 6079;\n            b.value6080 = 6080;\n            b.value6081 = 6081;\n            b.value6082 = 6082;\n            b.value6083 = 6083;\n            b.value6084 = 6084;\n            b.value6085 = 6085;\n            b.value6086 = 6086;\n            b.value6087 = 6087;\n            b.value6088 = 6088;\n            b.value6089 = 6089;\n            b.value6090 = 6090;\n            b.value6091 = 6091;\n            b.value6092 = 6092;\n            b.value6093 = 6093;\n            b.value6094 = 6094;\n            b.value6095 = 6095;\n            b.value6096 = 6096;\n            b.value6097 = 6097;\n            b.value6098 = 6098;\n            b.value6099 = 6099;\n            b.value6100 = 6100;\n            b.value6101 = 6101;\n            b.value6102 = 6102;\n            b.value6103 = 6103;\n            b.value6104 = 6104;\n            b.value6105 = 6105;\n            b.value6106 = 6106;\n            b.value6107 = 6107;\n            b.value6108 = 6108;\n            b.value6109 = 6109;\n            b.value6110 = 6110;\n            b.value6111 = 6111;\n            b.value6112 = 6112;\n            b.value6113 = 6113;\n            b.value6114 = 6114;\n            b.value6115 = 6115;\n            b.value6116 = 6116;\n            b.value6117 = 6117;\n            b.value6118 = 6118;\n            b.value6119 = 6119;\n            b.value6120 = 6120;\n            b.value6121 = 6121;\n            b.value6122 = 6122;\n            b.value6123 = 6123;\n            b.value6124 = 6124;\n            b.value6125 = 6125;\n            b.value6126 = 6126;\n            b.value6127 = 6127;\n            b.value6128 = 6128;\n            b.value6129 = 6129;\n            b.value6130 = 6130;\n            b.value6131 = 6131;\n            b.value6132 = 6132;\n            b.value6133 = 6133;\n            b.value6134 = 6134;\n            b.value6135 = 6135;\n            b.value6136 = 6136;\n            b.value6137 = 6137;\n            b.value6138 = 6138;\n            b.value6139 = 6139;\n            b.value6140 = 6140;\n            b.value6141 = 6141;\n            b.value6142 = 6142;\n            b.value6143 = 6143;\n            b.value6144 = 6144;\n            b.value6145 = 6145;\n            b.value6146 = 6146;\n            b.value6147 = 6147;\n            b.value6148 = 6148;\n            b.value6149 = 6149;\n            b.value6150 = 6150;\n            b.value6151 = 6151;\n            b.value6152 = 6152;\n            b.value6153 = 6153;\n            b.value6154 = 6154;\n            b.value6155 = 6155;\n            b.value6156 = 6156;\n            b.value6157 = 6157;\n            b.value6158 = 6158;\n            b.value6159 = 6159;\n            b.value6160 = 6160;\n            b.value6161 = 6161;\n            b.value6162 = 6162;\n            b.value6163 = 6163;\n            b.value6164 = 6164;\n            b.value6165 = 6165;\n            b.value6166 = 6166;\n            b.value6167 = 6167;\n            b.value6168 = 6168;\n            b.value6169 = 6169;\n            b.value6170 = 6170;\n            b.value6171 = 6171;\n            b.value6172 = 6172;\n            b.value6173 = 6173;\n            b.value6174 = 6174;\n            b.value6175 = 6175;\n            b.value6176 = 6176;\n            b.value6177 = 6177;\n            b.value6178 = 6178;\n            b.value6179 = 6179;\n            b.value6180 = 6180;\n            b.value6181 = 6181;\n            b.value6182 = 6182;\n            b.value6183 = 6183;\n            b.value6184 = 6184;\n            b.value6185 = 6185;\n            b.value6186 = 6186;\n            b.value6187 = 6187;\n            b.value6188 = 6188;\n            b.value6189 = 6189;\n            b.value6190 = 6190;\n            b.value6191 = 6191;\n            b.value6192 = 6192;\n            b.value6193 = 6193;\n            b.value6194 = 6194;\n            b.value6195 = 6195;\n            b.value6196 = 6196;\n            b.value6197 = 6197;\n            b.value6198 = 6198;\n            b.value6199 = 6199;\n            b.value6200 = 6200;\n            b.value6201 = 6201;\n            b.value6202 = 6202;\n            b.value6203 = 6203;\n            b.value6204 = 6204;\n            b.value6205 = 6205;\n            b.value6206 = 6206;\n            b.value6207 = 6207;\n            b.value6208 = 6208;\n            b.value6209 = 6209;\n            b.value6210 = 6210;\n            b.value6211 = 6211;\n            b.value6212 = 6212;\n            b.value6213 = 6213;\n            b.value6214 = 6214;\n            b.value6215 = 6215;\n            b.value6216 = 6216;\n            b.value6217 = 6217;\n            b.value6218 = 6218;\n            b.value6219 = 6219;\n            b.value6220 = 6220;\n            b.value6221 = 6221;\n            b.value6222 = 6222;\n            b.value6223 = 6223;\n            b.value6224 = 6224;\n            b.value6225 = 6225;\n            b.value6226 = 6226;\n            b.value6227 = 6227;\n            b.value6228 = 6228;\n            b.value6229 = 6229;\n            b.value6230 = 6230;\n            b.value6231 = 6231;\n            b.value6232 = 6232;\n            b.value6233 = 6233;\n            b.value6234 = 6234;\n            b.value6235 = 6235;\n            b.value6236 = 6236;\n            b.value6237 = 6237;\n            b.value6238 = 6238;\n            b.value6239 = 6239;\n            b.value6240 = 6240;\n            b.value6241 = 6241;\n            b.value6242 = 6242;\n            b.value6243 = 6243;\n            b.value6244 = 6244;\n            b.value6245 = 6245;\n            b.value6246 = 6246;\n            b.value6247 = 6247;\n            b.value6248 = 6248;\n            b.value6249 = 6249;\n            b.value6250 = 6250;\n            b.value6251 = 6251;\n            b.value6252 = 6252;\n            b.value6253 = 6253;\n            b.value6254 = 6254;\n            b.value6255 = 6255;\n            b.value6256 = 6256;\n            b.value6257 = 6257;\n            b.value6258 = 6258;\n            b.value6259 = 6259;\n            b.value6260 = 6260;\n            b.value6261 = 6261;\n            b.value6262 = 6262;\n            b.value6263 = 6263;\n            b.value6264 = 6264;\n            b.value6265 = 6265;\n            b.value6266 = 6266;\n            b.value6267 = 6267;\n            b.value6268 = 6268;\n            b.value6269 = 6269;\n            b.value6270 = 6270;\n            b.value6271 = 6271;\n            b.value6272 = 6272;\n            b.value6273 = 6273;\n            b.value6274 = 6274;\n            b.value6275 = 6275;\n            b.value6276 = 6276;\n            b.value6277 = 6277;\n            b.value6278 = 6278;\n            b.value6279 = 6279;\n            b.value6280 = 6280;\n            b.value6281 = 6281;\n            b.value6282 = 6282;\n            b.value6283 = 6283;\n            b.value6284 = 6284;\n            b.value6285 = 6285;\n            b.value6286 = 6286;\n            b.value6287 = 6287;\n            b.value6288 = 6288;\n            b.value6289 = 6289;\n            b.value6290 = 6290;\n            b.value6291 = 6291;\n            b.value6292 = 6292;\n            b.value6293 = 6293;\n            b.value6294 = 6294;\n            b.value6295 = 6295;\n            b.value6296 = 6296;\n            b.value6297 = 6297;\n            b.value6298 = 6298;\n            b.value6299 = 6299;\n            b.value6300 = 6300;\n            b.value6301 = 6301;\n            b.value6302 = 6302;\n            b.value6303 = 6303;\n            b.value6304 = 6304;\n            b.value6305 = 6305;\n            b.value6306 = 6306;\n            b.value6307 = 6307;\n            b.value6308 = 6308;\n            b.value6309 = 6309;\n            b.value6310 = 6310;\n            b.value6311 = 6311;\n            b.value6312 = 6312;\n            b.value6313 = 6313;\n            b.value6314 = 6314;\n            b.value6315 = 6315;\n            b.value6316 = 6316;\n            b.value6317 = 6317;\n            b.value6318 = 6318;\n            b.value6319 = 6319;\n            b.value6320 = 6320;\n            b.value6321 = 6321;\n            b.value6322 = 6322;\n            b.value6323 = 6323;\n            b.value6324 = 6324;\n            b.value6325 = 6325;\n            b.value6326 = 6326;\n            b.value6327 = 6327;\n            b.value6328 = 6328;\n            b.value6329 = 6329;\n            b.value6330 = 6330;\n            b.value6331 = 6331;\n            b.value6332 = 6332;\n            b.value6333 = 6333;\n            b.value6334 = 6334;\n            b.value6335 = 6335;\n            b.value6336 = 6336;\n            b.value6337 = 6337;\n            b.value6338 = 6338;\n            b.value6339 = 6339;\n            b.value6340 = 6340;\n            b.value6341 = 6341;\n            b.value6342 = 6342;\n            b.value6343 = 6343;\n            b.value6344 = 6344;\n            b.value6345 = 6345;\n            b.value6346 = 6346;\n            b.value6347 = 6347;\n            b.value6348 = 6348;\n            b.value6349 = 6349;\n            b.value6350 = 6350;\n            b.value6351 = 6351;\n            b.value6352 = 6352;\n            b.value6353 = 6353;\n            b.value6354 = 6354;\n            b.value6355 = 6355;\n            b.value6356 = 6356;\n            b.value6357 = 6357;\n            b.value6358 = 6358;\n            b.value6359 = 6359;\n            b.value6360 = 6360;\n            b.value6361 = 6361;\n            b.value6362 = 6362;\n            b.value6363 = 6363;\n            b.value6364 = 6364;\n            b.value6365 = 6365;\n            b.value6366 = 6366;\n            b.value6367 = 6367;\n            b.value6368 = 6368;\n            b.value6369 = 6369;\n            b.value6370 = 6370;\n            b.value6371 = 6371;\n            b.value6372 = 6372;\n            b.value6373 = 6373;\n            b.value6374 = 6374;\n            b.value6375 = 6375;\n            b.value6376 = 6376;\n            b.value6377 = 6377;\n            b.value6378 = 6378;\n            b.value6379 = 6379;\n            b.value6380 = 6380;\n            b.value6381 = 6381;\n            b.value6382 = 6382;\n            b.value6383 = 6383;\n            b.value6384 = 6384;\n            b.value6385 = 6385;\n            b.value6386 = 6386;\n            b.value6387 = 6387;\n            b.value6388 = 6388;\n            b.value6389 = 6389;\n            b.value6390 = 6390;\n            b.value6391 = 6391;\n            b.value6392 = 6392;\n            b.value6393 = 6393;\n            b.value6394 = 6394;\n            b.value6395 = 6395;\n            b.value6396 = 6396;\n            b.value6397 = 6397;\n            b.value6398 = 6398;\n            b.value6399 = 6399;\n            b.value6400 = 6400;\n            b.value6401 = 6401;\n            b.value6402 = 6402;\n            b.value6403 = 6403;\n            b.value6404 = 6404;\n            b.value6405 = 6405;\n            b.value6406 = 6406;\n            b.value6407 = 6407;\n            b.value6408 = 6408;\n            b.value6409 = 6409;\n            b.value6410 = 6410;\n            b.value6411 = 6411;\n            b.value6412 = 6412;\n            b.value6413 = 6413;\n            b.value6414 = 6414;\n            b.value6415 = 6415;\n            b.value6416 = 6416;\n            b.value6417 = 6417;\n            b.value6418 = 6418;\n            b.value6419 = 6419;\n            b.value6420 = 6420;\n            b.value6421 = 6421;\n            b.value6422 = 6422;\n            b.value6423 = 6423;\n            b.value6424 = 6424;\n            b.value6425 = 6425;\n            b.value6426 = 6426;\n            b.value6427 = 6427;\n            b.value6428 = 6428;\n            b.value6429 = 6429;\n            b.value6430 = 6430;\n            b.value6431 = 6431;\n            b.value6432 = 6432;\n            b.value6433 = 6433;\n            b.value6434 = 6434;\n            b.value6435 = 6435;\n            b.value6436 = 6436;\n            b.value6437 = 6437;\n            b.value6438 = 6438;\n            b.value6439 = 6439;\n            b.value6440 = 6440;\n            b.value6441 = 6441;\n            b.value6442 = 6442;\n            b.value6443 = 6443;\n            b.value6444 = 6444;\n            b.value6445 = 6445;\n            b.value6446 = 6446;\n            b.value6447 = 6447;\n            b.value6448 = 6448;\n            b.value6449 = 6449;\n            b.value6450 = 6450;\n            b.value6451 = 6451;\n            b.value6452 = 6452;\n            b.value6453 = 6453;\n            b.value6454 = 6454;\n            b.value6455 = 6455;\n            b.value6456 = 6456;\n            b.value6457 = 6457;\n            b.value6458 = 6458;\n            b.value6459 = 6459;\n            b.value6460 = 6460;\n            b.value6461 = 6461;\n            b.value6462 = 6462;\n            b.value6463 = 6463;\n            b.value6464 = 6464;\n            b.value6465 = 6465;\n            b.value6466 = 6466;\n            b.value6467 = 6467;\n            b.value6468 = 6468;\n            b.value6469 = 6469;\n            b.value6470 = 6470;\n            b.value6471 = 6471;\n            b.value6472 = 6472;\n            b.value6473 = 6473;\n            b.value6474 = 6474;\n            b.value6475 = 6475;\n            b.value6476 = 6476;\n            b.value6477 = 6477;\n            b.value6478 = 6478;\n            b.value6479 = 6479;\n            b.value6480 = 6480;\n            b.value6481 = 6481;\n            b.value6482 = 6482;\n            b.value6483 = 6483;\n            b.value6484 = 6484;\n            b.value6485 = 6485;\n            b.value6486 = 6486;\n            b.value6487 = 6487;\n            b.value6488 = 6488;\n            b.value6489 = 6489;\n            b.value6490 = 6490;\n            b.value6491 = 6491;\n            b.value6492 = 6492;\n            b.value6493 = 6493;\n            b.value6494 = 6494;\n            b.value6495 = 6495;\n            b.value6496 = 6496;\n            b.value6497 = 6497;\n            b.value6498 = 6498;\n            b.value6499 = 6499;\n            b.value6500 = 6500;\n            b.value6501 = 6501;\n            b.value6502 = 6502;\n            b.value6503 = 6503;\n            b.value6504 = 6504;\n            b.value6505 = 6505;\n            b.value6506 = 6506;\n            b.value6507 = 6507;\n            b.value6508 = 6508;\n            b.value6509 = 6509;\n            b.value6510 = 6510;\n            b.value6511 = 6511;\n            b.value6512 = 6512;\n            b.value6513 = 6513;\n            b.value6514 = 6514;\n            b.value6515 = 6515;\n            b.value6516 = 6516;\n            b.value6517 = 6517;\n            b.value6518 = 6518;\n            b.value6519 = 6519;\n            b.value6520 = 6520;\n            b.value6521 = 6521;\n            b.value6522 = 6522;\n            b.value6523 = 6523;\n            b.value6524 = 6524;\n            b.value6525 = 6525;\n            b.value6526 = 6526;\n            b.value6527 = 6527;\n            b.value6528 = 6528;\n            b.value6529 = 6529;\n            b.value6530 = 6530;\n            b.value6531 = 6531;\n            b.value6532 = 6532;\n            b.value6533 = 6533;\n            b.value6534 = 6534;\n            b.value6535 = 6535;\n            b.value6536 = 6536;\n            b.value6537 = 6537;\n            b.value6538 = 6538;\n            b.value6539 = 6539;\n            b.value6540 = 6540;\n            b.value6541 = 6541;\n            b.value6542 = 6542;\n            b.value6543 = 6543;\n            b.value6544 = 6544;\n            b.value6545 = 6545;\n            b.value6546 = 6546;\n            b.value6547 = 6547;\n            b.value6548 = 6548;\n            b.value6549 = 6549;\n            b.value6550 = 6550;\n            b.value6551 = 6551;\n            b.value6552 = 6552;\n            b.value6553 = 6553;\n            b.value6554 = 6554;\n            b.value6555 = 6555;\n            b.value6556 = 6556;\n            b.value6557 = 6557;\n            b.value6558 = 6558;\n            b.value6559 = 6559;\n            b.value6560 = 6560;\n            b.value6561 = 6561;\n            b.value6562 = 6562;\n            b.value6563 = 6563;\n            b.value6564 = 6564;\n            b.value6565 = 6565;\n            b.value6566 = 6566;\n            b.value6567 = 6567;\n            b.value6568 = 6568;\n            b.value6569 = 6569;\n            b.value6570 = 6570;\n            b.value6571 = 6571;\n            b.value6572 = 6572;\n            b.value6573 = 6573;\n            b.value6574 = 6574;\n            b.value6575 = 6575;\n            b.value6576 = 6576;\n            b.value6577 = 6577;\n            b.value6578 = 6578;\n            b.value6579 = 6579;\n            b.value6580 = 6580;\n            b.value6581 = 6581;\n            b.value6582 = 6582;\n            b.value6583 = 6583;\n            b.value6584 = 6584;\n            b.value6585 = 6585;\n            b.value6586 = 6586;\n            b.value6587 = 6587;\n            b.value6588 = 6588;\n            b.value6589 = 6589;\n            b.value6590 = 6590;\n            b.value6591 = 6591;\n            b.value6592 = 6592;\n            b.value6593 = 6593;\n            b.value6594 = 6594;\n            b.value6595 = 6595;\n            b.value6596 = 6596;\n            b.value6597 = 6597;\n            b.value6598 = 6598;\n            b.value6599 = 6599;\n            b.value6600 = 6600;\n            b.value6601 = 6601;\n            b.value6602 = 6602;\n            b.value6603 = 6603;\n            b.value6604 = 6604;\n            b.value6605 = 6605;\n            b.value6606 = 6606;\n            b.value6607 = 6607;\n            b.value6608 = 6608;\n            b.value6609 = 6609;\n            b.value6610 = 6610;\n            b.value6611 = 6611;\n            b.value6612 = 6612;\n            b.value6613 = 6613;\n            b.value6614 = 6614;\n            b.value6615 = 6615;\n            b.value6616 = 6616;\n            b.value6617 = 6617;\n            b.value6618 = 6618;\n            b.value6619 = 6619;\n            b.value6620 = 6620;\n            b.value6621 = 6621;\n            b.value6622 = 6622;\n            b.value6623 = 6623;\n            b.value6624 = 6624;\n            b.value6625 = 6625;\n            b.value6626 = 6626;\n            b.value6627 = 6627;\n            b.value6628 = 6628;\n            b.value6629 = 6629;\n            b.value6630 = 6630;\n            b.value6631 = 6631;\n            b.value6632 = 6632;\n            b.value6633 = 6633;\n            b.value6634 = 6634;\n            b.value6635 = 6635;\n            b.value6636 = 6636;\n            b.value6637 = 6637;\n            b.value6638 = 6638;\n            b.value6639 = 6639;\n            b.value6640 = 6640;\n            b.value6641 = 6641;\n            b.value6642 = 6642;\n            b.value6643 = 6643;\n            b.value6644 = 6644;\n            b.value6645 = 6645;\n            b.value6646 = 6646;\n            b.value6647 = 6647;\n            b.value6648 = 6648;\n            b.value6649 = 6649;\n            b.value6650 = 6650;\n            b.value6651 = 6651;\n            b.value6652 = 6652;\n            b.value6653 = 6653;\n            b.value6654 = 6654;\n            b.value6655 = 6655;\n            b.value6656 = 6656;\n            b.value6657 = 6657;\n            b.value6658 = 6658;\n            b.value6659 = 6659;\n            b.value6660 = 6660;\n            b.value6661 = 6661;\n            b.value6662 = 6662;\n            b.value6663 = 6663;\n            b.value6664 = 6664;\n            b.value6665 = 6665;\n            b.value6666 = 6666;\n            b.value6667 = 6667;\n            b.value6668 = 6668;\n            b.value6669 = 6669;\n            b.value6670 = 6670;\n            b.value6671 = 6671;\n            b.value6672 = 6672;\n            b.value6673 = 6673;\n            b.value6674 = 6674;\n            b.value6675 = 6675;\n            b.value6676 = 6676;\n            b.value6677 = 6677;\n            b.value6678 = 6678;\n            b.value6679 = 6679;\n            b.value6680 = 6680;\n            b.value6681 = 6681;\n            b.value6682 = 6682;\n            b.value6683 = 6683;\n            b.value6684 = 6684;\n            b.value6685 = 6685;\n            b.value6686 = 6686;\n            b.value6687 = 6687;\n            b.value6688 = 6688;\n            b.value6689 = 6689;\n            b.value6690 = 6690;\n            b.value6691 = 6691;\n            b.value6692 = 6692;\n            b.value6693 = 6693;\n            b.value6694 = 6694;\n            b.value6695 = 6695;\n            b.value6696 = 6696;\n            b.value6697 = 6697;\n            b.value6698 = 6698;\n            b.value6699 = 6699;\n            b.value6700 = 6700;\n            b.value6701 = 6701;\n            b.value6702 = 6702;\n            b.value6703 = 6703;\n            b.value6704 = 6704;\n            b.value6705 = 6705;\n            b.value6706 = 6706;\n            b.value6707 = 6707;\n            b.value6708 = 6708;\n            b.value6709 = 6709;\n            b.value6710 = 6710;\n            b.value6711 = 6711;\n            b.value6712 = 6712;\n            b.value6713 = 6713;\n            b.value6714 = 6714;\n            b.value6715 = 6715;\n            b.value6716 = 6716;\n            b.value6717 = 6717;\n            b.value6718 = 6718;\n            b.value6719 = 6719;\n            b.value6720 = 6720;\n            b.value6721 = 6721;\n            b.value6722 = 6722;\n            b.value6723 = 6723;\n            b.value6724 = 6724;\n            b.value6725 = 6725;\n            b.value6726 = 6726;\n            b.value6727 = 6727;\n            b.value6728 = 6728;\n            b.value6729 = 6729;\n            b.value6730 = 6730;\n            b.value6731 = 6731;\n            b.value6732 = 6732;\n            b.value6733 = 6733;\n            b.value6734 = 6734;\n            b.value6735 = 6735;\n            b.value6736 = 6736;\n            b.value6737 = 6737;\n            b.value6738 = 6738;\n            b.value6739 = 6739;\n            b.value6740 = 6740;\n            b.value6741 = 6741;\n            b.value6742 = 6742;\n            b.value6743 = 6743;\n            b.value6744 = 6744;\n            b.value6745 = 6745;\n            b.value6746 = 6746;\n            b.value6747 = 6747;\n            b.value6748 = 6748;\n            b.value6749 = 6749;\n            b.value6750 = 6750;\n            b.value6751 = 6751;\n            b.value6752 = 6752;\n            b.value6753 = 6753;\n            b.value6754 = 6754;\n            b.value6755 = 6755;\n            b.value6756 = 6756;\n            b.value6757 = 6757;\n            b.value6758 = 6758;\n            b.value6759 = 6759;\n            b.value6760 = 6760;\n            b.value6761 = 6761;\n            b.value6762 = 6762;\n            b.value6763 = 6763;\n            b.value6764 = 6764;\n            b.value6765 = 6765;\n            b.value6766 = 6766;\n            b.value6767 = 6767;\n            b.value6768 = 6768;\n            b.value6769 = 6769;\n            b.value6770 = 6770;\n            b.value6771 = 6771;\n            b.value6772 = 6772;\n            b.value6773 = 6773;\n            b.value6774 = 6774;\n            b.value6775 = 6775;\n            b.value6776 = 6776;\n            b.value6777 = 6777;\n            b.value6778 = 6778;\n            b.value6779 = 6779;\n            b.value6780 = 6780;\n            b.value6781 = 6781;\n            b.value6782 = 6782;\n            b.value6783 = 6783;\n            b.value6784 = 6784;\n            b.value6785 = 6785;\n            b.value6786 = 6786;\n            b.value6787 = 6787;\n            b.value6788 = 6788;\n            b.value6789 = 6789;\n            b.value6790 = 6790;\n            b.value6791 = 6791;\n            b.value6792 = 6792;\n            b.value6793 = 6793;\n            b.value6794 = 6794;\n            b.value6795 = 6795;\n            b.value6796 = 6796;\n            b.value6797 = 6797;\n            b.value6798 = 6798;\n            b.value6799 = 6799;\n            b.value6800 = 6800;\n            b.value6801 = 6801;\n            b.value6802 = 6802;\n            b.value6803 = 6803;\n            b.value6804 = 6804;\n            b.value6805 = 6805;\n            b.value6806 = 6806;\n            b.value6807 = 6807;\n            b.value6808 = 6808;\n            b.value6809 = 6809;\n            b.value6810 = 6810;\n            b.value6811 = 6811;\n            b.value6812 = 6812;\n            b.value6813 = 6813;\n            b.value6814 = 6814;\n            b.value6815 = 6815;\n            b.value6816 = 6816;\n            b.value6817 = 6817;\n            b.value6818 = 6818;\n            b.value6819 = 6819;\n            b.value6820 = 6820;\n            b.value6821 = 6821;\n            b.value6822 = 6822;\n            b.value6823 = 6823;\n            b.value6824 = 6824;\n            b.value6825 = 6825;\n            b.value6826 = 6826;\n            b.value6827 = 6827;\n            b.value6828 = 6828;\n            b.value6829 = 6829;\n            b.value6830 = 6830;\n            b.value6831 = 6831;\n            b.value6832 = 6832;\n            b.value6833 = 6833;\n            b.value6834 = 6834;\n            b.value6835 = 6835;\n            b.value6836 = 6836;\n            b.value6837 = 6837;\n            b.value6838 = 6838;\n            b.value6839 = 6839;\n            b.value6840 = 6840;\n            b.value6841 = 6841;\n            b.value6842 = 6842;\n            b.value6843 = 6843;\n            b.value6844 = 6844;\n            b.value6845 = 6845;\n            b.value6846 = 6846;\n            b.value6847 = 6847;\n            b.value6848 = 6848;\n            b.value6849 = 6849;\n            b.value6850 = 6850;\n            b.value6851 = 6851;\n            b.value6852 = 6852;\n            b.value6853 = 6853;\n            b.value6854 = 6854;\n            b.value6855 = 6855;\n            b.value6856 = 6856;\n            b.value6857 = 6857;\n            b.value6858 = 6858;\n            b.value6859 = 6859;\n            b.value6860 = 6860;\n            b.value6861 = 6861;\n            b.value6862 = 6862;\n            b.value6863 = 6863;\n            b.value6864 = 6864;\n            b.value6865 = 6865;\n            b.value6866 = 6866;\n            b.value6867 = 6867;\n            b.value6868 = 6868;\n            b.value6869 = 6869;\n            b.value6870 = 6870;\n            b.value6871 = 6871;\n            b.value6872 = 6872;\n            b.value6873 = 6873;\n            b.value6874 = 6874;\n            b.value6875 = 6875;\n            b.value6876 = 6876;\n            b.value6877 = 6877;\n            b.value6878 = 6878;\n            b.value6879 = 6879;\n            b.value6880 = 6880;\n            b.value6881 = 6881;\n            b.value6882 = 6882;\n            b.value6883 = 6883;\n            b.value6884 = 6884;\n            b.value6885 = 6885;\n            b.value6886 = 6886;\n            b.value6887 = 6887;\n            b.value6888 = 6888;\n            b.value6889 = 6889;\n            b.value6890 = 6890;\n            b.value6891 = 6891;\n            b.value6892 = 6892;\n            b.value6893 = 6893;\n            b.value6894 = 6894;\n            b.value6895 = 6895;\n            b.value6896 = 6896;\n            b.value6897 = 6897;\n            b.value6898 = 6898;\n            b.value6899 = 6899;\n            b.value6900 = 6900;\n            b.value6901 = 6901;\n            b.value6902 = 6902;\n            b.value6903 = 6903;\n            b.value6904 = 6904;\n            b.value6905 = 6905;\n            b.value6906 = 6906;\n            b.value6907 = 6907;\n            b.value6908 = 6908;\n            b.value6909 = 6909;\n            b.value6910 = 6910;\n            b.value6911 = 6911;\n            b.value6912 = 6912;\n            b.value6913 = 6913;\n            b.value6914 = 6914;\n            b.value6915 = 6915;\n            b.value6916 = 6916;\n            b.value6917 = 6917;\n            b.value6918 = 6918;\n            b.value6919 = 6919;\n            b.value6920 = 6920;\n            b.value6921 = 6921;\n            b.value6922 = 6922;\n            b.value6923 = 6923;\n            b.value6924 = 6924;\n            b.value6925 = 6925;\n            b.value6926 = 6926;\n            b.value6927 = 6927;\n            b.value6928 = 6928;\n            b.value6929 = 6929;\n            b.value6930 = 6930;\n            b.value6931 = 6931;\n            b.value6932 = 6932;\n            b.value6933 = 6933;\n            b.value6934 = 6934;\n            b.value6935 = 6935;\n            b.value6936 = 6936;\n            b.value6937 = 6937;\n            b.value6938 = 6938;\n            b.value6939 = 6939;\n            b.value6940 = 6940;\n            b.value6941 = 6941;\n            b.value6942 = 6942;\n            b.value6943 = 6943;\n            b.value6944 = 6944;\n            b.value6945 = 6945;\n            b.value6946 = 6946;\n            b.value6947 = 6947;\n            b.value6948 = 6948;\n            b.value6949 = 6949;\n            b.value6950 = 6950;\n            b.value6951 = 6951;\n            b.value6952 = 6952;\n            b.value6953 = 6953;\n            b.value6954 = 6954;\n            b.value6955 = 6955;\n            b.value6956 = 6956;\n            b.value6957 = 6957;\n            b.value6958 = 6958;\n            b.value6959 = 6959;\n            b.value6960 = 6960;\n            b.value6961 = 6961;\n            b.value6962 = 6962;\n            b.value6963 = 6963;\n            b.value6964 = 6964;\n            b.value6965 = 6965;\n            b.value6966 = 6966;\n            b.value6967 = 6967;\n            b.value6968 = 6968;\n            b.value6969 = 6969;\n            b.value6970 = 6970;\n            b.value6971 = 6971;\n            b.value6972 = 6972;\n            b.value6973 = 6973;\n            b.value6974 = 6974;\n            b.value6975 = 6975;\n            b.value6976 = 6976;\n            b.value6977 = 6977;\n            b.value6978 = 6978;\n            b.value6979 = 6979;\n            b.value6980 = 6980;\n            b.value6981 = 6981;\n            b.value6982 = 6982;\n            b.value6983 = 6983;\n            b.value6984 = 6984;\n            b.value6985 = 6985;\n            b.value6986 = 6986;\n            b.value6987 = 6987;\n            b.value6988 = 6988;\n            b.value6989 = 6989;\n            b.value6990 = 6990;\n            b.value6991 = 6991;\n            b.value6992 = 6992;\n            b.value6993 = 6993;\n            b.value6994 = 6994;\n            b.value6995 = 6995;\n            b.value6996 = 6996;\n            b.value6997 = 6997;\n            b.value6998 = 6998;\n            b.value6999 = 6999;\n            b.value7000 = 7000;\n            b.value7001 = 7001;\n            b.value7002 = 7002;\n            b.value7003 = 7003;\n            b.value7004 = 7004;\n            b.value7005 = 7005;\n            b.value7006 = 7006;\n            b.value7007 = 7007;\n            b.value7008 = 7008;\n            b.value7009 = 7009;\n            b.value7010 = 7010;\n            b.value7011 = 7011;\n            b.value7012 = 7012;\n            b.value7013 = 7013;\n            b.value7014 = 7014;\n            b.value7015 = 7015;\n            b.value7016 = 7016;\n            b.value7017 = 7017;\n            b.value7018 = 7018;\n            b.value7019 = 7019;\n            b.value7020 = 7020;\n            b.value7021 = 7021;\n            b.value7022 = 7022;\n            b.value7023 = 7023;\n            b.value7024 = 7024;\n            b.value7025 = 7025;\n            b.value7026 = 7026;\n            b.value7027 = 7027;\n            b.value7028 = 7028;\n            b.value7029 = 7029;\n            b.value7030 = 7030;\n            b.value7031 = 7031;\n            b.value7032 = 7032;\n            b.value7033 = 7033;\n            b.value7034 = 7034;\n            b.value7035 = 7035;\n            b.value7036 = 7036;\n            b.value7037 = 7037;\n            b.value7038 = 7038;\n            b.value7039 = 7039;\n            b.value7040 = 7040;\n            b.value7041 = 7041;\n            b.value7042 = 7042;\n            b.value7043 = 7043;\n            b.value7044 = 7044;\n            b.value7045 = 7045;\n            b.value7046 = 7046;\n            b.value7047 = 7047;\n            b.value7048 = 7048;\n            b.value7049 = 7049;\n            b.value7050 = 7050;\n            b.value7051 = 7051;\n            b.value7052 = 7052;\n            b.value7053 = 7053;\n            b.value7054 = 7054;\n            b.value7055 = 7055;\n            b.value7056 = 7056;\n            b.value7057 = 7057;\n            b.value7058 = 7058;\n            b.value7059 = 7059;\n            b.value7060 = 7060;\n            b.value7061 = 7061;\n            b.value7062 = 7062;\n            b.value7063 = 7063;\n            b.value7064 = 7064;\n            b.value7065 = 7065;\n            b.value7066 = 7066;\n            b.value7067 = 7067;\n            b.value7068 = 7068;\n            b.value7069 = 7069;\n            b.value7070 = 7070;\n            b.value7071 = 7071;\n            b.value7072 = 7072;\n            b.value7073 = 7073;\n            b.value7074 = 7074;\n            b.value7075 = 7075;\n            b.value7076 = 7076;\n            b.value7077 = 7077;\n            b.value7078 = 7078;\n            b.value7079 = 7079;\n            b.value7080 = 7080;\n            b.value7081 = 7081;\n            b.value7082 = 7082;\n            b.value7083 = 7083;\n            b.value7084 = 7084;\n            b.value7085 = 7085;\n            b.value7086 = 7086;\n            b.value7087 = 7087;\n            b.value7088 = 7088;\n            b.value7089 = 7089;\n            b.value7090 = 7090;\n            b.value7091 = 7091;\n            b.value7092 = 7092;\n            b.value7093 = 7093;\n            b.value7094 = 7094;\n            b.value7095 = 7095;\n            b.value7096 = 7096;\n            b.value7097 = 7097;\n            b.value7098 = 7098;\n            b.value7099 = 7099;\n            b.value7100 = 7100;\n            b.value7101 = 7101;\n            b.value7102 = 7102;\n            b.value7103 = 7103;\n            b.value7104 = 7104;\n            b.value7105 = 7105;\n            b.value7106 = 7106;\n            b.value7107 = 7107;\n            b.value7108 = 7108;\n            b.value7109 = 7109;\n            b.value7110 = 7110;\n            b.value7111 = 7111;\n            b.value7112 = 7112;\n            b.value7113 = 7113;\n            b.value7114 = 7114;\n            b.value7115 = 7115;\n            b.value7116 = 7116;\n            b.value7117 = 7117;\n            b.value7118 = 7118;\n            b.value7119 = 7119;\n            b.value7120 = 7120;\n            b.value7121 = 7121;\n            b.value7122 = 7122;\n            b.value7123 = 7123;\n            b.value7124 = 7124;\n            b.value7125 = 7125;\n            b.value7126 = 7126;\n            b.value7127 = 7127;\n            b.value7128 = 7128;\n            b.value7129 = 7129;\n            b.value7130 = 7130;\n            b.value7131 = 7131;\n            b.value7132 = 7132;\n            b.value7133 = 7133;\n            b.value7134 = 7134;\n            b.value7135 = 7135;\n            b.value7136 = 7136;\n            b.value7137 = 7137;\n            b.value7138 = 7138;\n            b.value7139 = 7139;\n            b.value7140 = 7140;\n            b.value7141 = 7141;\n            b.value7142 = 7142;\n            b.value7143 = 7143;\n            b.value7144 = 7144;\n            b.value7145 = 7145;\n            b.value7146 = 7146;\n            b.value7147 = 7147;\n            b.value7148 = 7148;\n            b.value7149 = 7149;\n            b.value7150 = 7150;\n            b.value7151 = 7151;\n            b.value7152 = 7152;\n            b.value7153 = 7153;\n            b.value7154 = 7154;\n            b.value7155 = 7155;\n            b.value7156 = 7156;\n            b.value7157 = 7157;\n            b.value7158 = 7158;\n            b.value7159 = 7159;\n            b.value7160 = 7160;\n            b.value7161 = 7161;\n            b.value7162 = 7162;\n            b.value7163 = 7163;\n            b.value7164 = 7164;\n            b.value7165 = 7165;\n            b.value7166 = 7166;\n            b.value7167 = 7167;\n            b.value7168 = 7168;\n            b.value7169 = 7169;\n            b.value7170 = 7170;\n            b.value7171 = 7171;\n            b.value7172 = 7172;\n            b.value7173 = 7173;\n            b.value7174 = 7174;\n            b.value7175 = 7175;\n            b.value7176 = 7176;\n            b.value7177 = 7177;\n            b.value7178 = 7178;\n            b.value7179 = 7179;\n            b.value7180 = 7180;\n            b.value7181 = 7181;\n            b.value7182 = 7182;\n            b.value7183 = 7183;\n            b.value7184 = 7184;\n            b.value7185 = 7185;\n            b.value7186 = 7186;\n            b.value7187 = 7187;\n            b.value7188 = 7188;\n            b.value7189 = 7189;\n            b.value7190 = 7190;\n            b.value7191 = 7191;\n            b.value7192 = 7192;\n            b.value7193 = 7193;\n            b.value7194 = 7194;\n            b.value7195 = 7195;\n            b.value7196 = 7196;\n            b.value7197 = 7197;\n            b.value7198 = 7198;\n            b.value7199 = 7199;\n            b.value7200 = 7200;\n            b.value7201 = 7201;\n            b.value7202 = 7202;\n            b.value7203 = 7203;\n            b.value7204 = 7204;\n            b.value7205 = 7205;\n            b.value7206 = 7206;\n            b.value7207 = 7207;\n            b.value7208 = 7208;\n            b.value7209 = 7209;\n            b.value7210 = 7210;\n            b.value7211 = 7211;\n            b.value7212 = 7212;\n            b.value7213 = 7213;\n            b.value7214 = 7214;\n            b.value7215 = 7215;\n            b.value7216 = 7216;\n            b.value7217 = 7217;\n            b.value7218 = 7218;\n            b.value7219 = 7219;\n            b.value7220 = 7220;\n            b.value7221 = 7221;\n            b.value7222 = 7222;\n            b.value7223 = 7223;\n            b.value7224 = 7224;\n            b.value7225 = 7225;\n            b.value7226 = 7226;\n            b.value7227 = 7227;\n            b.value7228 = 7228;\n            b.value7229 = 7229;\n            b.value7230 = 7230;\n            b.value7231 = 7231;\n            b.value7232 = 7232;\n            b.value7233 = 7233;\n            b.value7234 = 7234;\n            b.value7235 = 7235;\n            b.value7236 = 7236;\n            b.value7237 = 7237;\n            b.value7238 = 7238;\n            b.value7239 = 7239;\n            b.value7240 = 7240;\n            b.value7241 = 7241;\n            b.value7242 = 7242;\n            b.value7243 = 7243;\n            b.value7244 = 7244;\n            b.value7245 = 7245;\n            b.value7246 = 7246;\n            b.value7247 = 7247;\n            b.value7248 = 7248;\n            b.value7249 = 7249;\n            b.value7250 = 7250;\n            b.value7251 = 7251;\n            b.value7252 = 7252;\n            b.value7253 = 7253;\n            b.value7254 = 7254;\n            b.value7255 = 7255;\n            b.value7256 = 7256;\n            b.value7257 = 7257;\n            b.value7258 = 7258;\n            b.value7259 = 7259;\n            b.value7260 = 7260;\n            b.value7261 = 7261;\n            b.value7262 = 7262;\n            b.value7263 = 7263;\n            b.value7264 = 7264;\n            b.value7265 = 7265;\n            b.value7266 = 7266;\n            b.value7267 = 7267;\n            b.value7268 = 7268;\n            b.value7269 = 7269;\n            b.value7270 = 7270;\n            b.value7271 = 7271;\n            b.value7272 = 7272;\n            b.value7273 = 7273;\n            b.value7274 = 7274;\n            b.value7275 = 7275;\n            b.value7276 = 7276;\n            b.value7277 = 7277;\n            b.value7278 = 7278;\n            b.value7279 = 7279;\n            b.value7280 = 7280;\n            b.value7281 = 7281;\n            b.value7282 = 7282;\n            b.value7283 = 7283;\n            b.value7284 = 7284;\n            b.value7285 = 7285;\n            b.value7286 = 7286;\n            b.value7287 = 7287;\n            b.value7288 = 7288;\n            b.value7289 = 7289;\n            b.value7290 = 7290;\n            b.value7291 = 7291;\n            b.value7292 = 7292;\n            b.value7293 = 7293;\n            b.value7294 = 7294;\n            b.value7295 = 7295;\n            b.value7296 = 7296;\n            b.value7297 = 7297;\n            b.value7298 = 7298;\n            b.value7299 = 7299;\n            b.value7300 = 7300;\n            b.value7301 = 7301;\n            b.value7302 = 7302;\n            b.value7303 = 7303;\n            b.value7304 = 7304;\n            b.value7305 = 7305;\n            b.value7306 = 7306;\n            b.value7307 = 7307;\n            b.value7308 = 7308;\n            b.value7309 = 7309;\n            b.value7310 = 7310;\n            b.value7311 = 7311;\n            b.value7312 = 7312;\n            b.value7313 = 7313;\n            b.value7314 = 7314;\n            b.value7315 = 7315;\n            b.value7316 = 7316;\n            b.value7317 = 7317;\n            b.value7318 = 7318;\n            b.value7319 = 7319;\n            b.value7320 = 7320;\n            b.value7321 = 7321;\n            b.value7322 = 7322;\n            b.value7323 = 7323;\n            b.value7324 = 7324;\n            b.value7325 = 7325;\n            b.value7326 = 7326;\n            b.value7327 = 7327;\n            b.value7328 = 7328;\n            b.value7329 = 7329;\n            b.value7330 = 7330;\n            b.value7331 = 7331;\n            b.value7332 = 7332;\n            b.value7333 = 7333;\n            b.value7334 = 7334;\n            b.value7335 = 7335;\n            b.value7336 = 7336;\n            b.value7337 = 7337;\n            b.value7338 = 7338;\n            b.value7339 = 7339;\n            b.value7340 = 7340;\n            b.value7341 = 7341;\n            b.value7342 = 7342;\n            b.value7343 = 7343;\n            b.value7344 = 7344;\n            b.value7345 = 7345;\n            b.value7346 = 7346;\n            b.value7347 = 7347;\n            b.value7348 = 7348;\n            b.value7349 = 7349;\n            b.value7350 = 7350;\n            b.value7351 = 7351;\n            b.value7352 = 7352;\n            b.value7353 = 7353;\n            b.value7354 = 7354;\n            b.value7355 = 7355;\n            b.value7356 = 7356;\n            b.value7357 = 7357;\n            b.value7358 = 7358;\n            b.value7359 = 7359;\n            b.value7360 = 7360;\n            b.value7361 = 7361;\n            b.value7362 = 7362;\n            b.value7363 = 7363;\n            b.value7364 = 7364;\n            b.value7365 = 7365;\n            b.value7366 = 7366;\n            b.value7367 = 7367;\n            b.value7368 = 7368;\n            b.value7369 = 7369;\n            b.value7370 = 7370;\n            b.value7371 = 7371;\n            b.value7372 = 7372;\n            b.value7373 = 7373;\n            b.value7374 = 7374;\n            b.value7375 = 7375;\n            b.value7376 = 7376;\n            b.value7377 = 7377;\n            b.value7378 = 7378;\n            b.value7379 = 7379;\n            b.value7380 = 7380;\n            b.value7381 = 7381;\n            b.value7382 = 7382;\n            b.value7383 = 7383;\n            b.value7384 = 7384;\n            b.value7385 = 7385;\n            b.value7386 = 7386;\n            b.value7387 = 7387;\n            b.value7388 = 7388;\n            b.value7389 = 7389;\n            b.value7390 = 7390;\n            b.value7391 = 7391;\n            b.value7392 = 7392;\n            b.value7393 = 7393;\n            b.value7394 = 7394;\n            b.value7395 = 7395;\n            b.value7396 = 7396;\n            b.value7397 = 7397;\n            b.value7398 = 7398;\n            b.value7399 = 7399;\n            b.value7400 = 7400;\n            b.value7401 = 7401;\n            b.value7402 = 7402;\n            b.value7403 = 7403;\n            b.value7404 = 7404;\n            b.value7405 = 7405;\n            b.value7406 = 7406;\n            b.value7407 = 7407;\n            b.value7408 = 7408;\n            b.value7409 = 7409;\n            b.value7410 = 7410;\n            b.value7411 = 7411;\n            b.value7412 = 7412;\n            b.value7413 = 7413;\n            b.value7414 = 7414;\n            b.value7415 = 7415;\n            b.value7416 = 7416;\n            b.value7417 = 7417;\n            b.value7418 = 7418;\n            b.value7419 = 7419;\n            b.value7420 = 7420;\n            b.value7421 = 7421;\n            b.value7422 = 7422;\n            b.value7423 = 7423;\n            b.value7424 = 7424;\n            b.value7425 = 7425;\n            b.value7426 = 7426;\n            b.value7427 = 7427;\n            b.value7428 = 7428;\n            b.value7429 = 7429;\n            b.value7430 = 7430;\n            b.value7431 = 7431;\n            b.value7432 = 7432;\n            b.value7433 = 7433;\n            b.value7434 = 7434;\n            b.value7435 = 7435;\n            b.value7436 = 7436;\n            b.value7437 = 7437;\n            b.value7438 = 7438;\n            b.value7439 = 7439;\n            b.value7440 = 7440;\n            b.value7441 = 7441;\n            b.value7442 = 7442;\n            b.value7443 = 7443;\n            b.value7444 = 7444;\n            b.value7445 = 7445;\n            b.value7446 = 7446;\n            b.value7447 = 7447;\n            b.value7448 = 7448;\n            b.value7449 = 7449;\n            b.value7450 = 7450;\n            b.value7451 = 7451;\n            b.value7452 = 7452;\n            b.value7453 = 7453;\n            b.value7454 = 7454;\n            b.value7455 = 7455;\n            b.value7456 = 7456;\n            b.value7457 = 7457;\n            b.value7458 = 7458;\n            b.value7459 = 7459;\n            b.value7460 = 7460;\n            b.value7461 = 7461;\n            b.value7462 = 7462;\n            b.value7463 = 7463;\n            b.value7464 = 7464;\n            b.value7465 = 7465;\n            b.value7466 = 7466;\n            b.value7467 = 7467;\n            b.value7468 = 7468;\n            b.value7469 = 7469;\n            b.value7470 = 7470;\n            b.value7471 = 7471;\n            b.value7472 = 7472;\n            b.value7473 = 7473;\n            b.value7474 = 7474;\n            b.value7475 = 7475;\n            b.value7476 = 7476;\n            b.value7477 = 7477;\n            b.value7478 = 7478;\n            b.value7479 = 7479;\n            b.value7480 = 7480;\n            b.value7481 = 7481;\n            b.value7482 = 7482;\n            b.value7483 = 7483;\n            b.value7484 = 7484;\n            b.value7485 = 7485;\n            b.value7486 = 7486;\n            b.value7487 = 7487;\n            b.value7488 = 7488;\n            b.value7489 = 7489;\n            b.value7490 = 7490;\n            b.value7491 = 7491;\n            b.value7492 = 7492;\n            b.value7493 = 7493;\n            b.value7494 = 7494;\n            b.value7495 = 7495;\n            b.value7496 = 7496;\n            b.value7497 = 7497;\n            b.value7498 = 7498;\n            b.value7499 = 7499;\n            b.value7500 = 7500;\n            b.value7501 = 7501;\n            b.value7502 = 7502;\n            b.value7503 = 7503;\n            b.value7504 = 7504;\n            b.value7505 = 7505;\n            b.value7506 = 7506;\n            b.value7507 = 7507;\n            b.value7508 = 7508;\n            b.value7509 = 7509;\n            b.value7510 = 7510;\n            b.value7511 = 7511;\n            b.value7512 = 7512;\n            b.value7513 = 7513;\n            b.value7514 = 7514;\n            b.value7515 = 7515;\n            b.value7516 = 7516;\n            b.value7517 = 7517;\n            b.value7518 = 7518;\n            b.value7519 = 7519;\n            b.value7520 = 7520;\n            b.value7521 = 7521;\n            b.value7522 = 7522;\n            b.value7523 = 7523;\n            b.value7524 = 7524;\n            b.value7525 = 7525;\n            b.value7526 = 7526;\n            b.value7527 = 7527;\n            b.value7528 = 7528;\n            b.value7529 = 7529;\n            b.value7530 = 7530;\n            b.value7531 = 7531;\n            b.value7532 = 7532;\n            b.value7533 = 7533;\n            b.value7534 = 7534;\n            b.value7535 = 7535;\n            b.value7536 = 7536;\n            b.value7537 = 7537;\n            b.value7538 = 7538;\n            b.value7539 = 7539;\n            b.value7540 = 7540;\n            b.value7541 = 7541;\n            b.value7542 = 7542;\n            b.value7543 = 7543;\n            b.value7544 = 7544;\n            b.value7545 = 7545;\n            b.value7546 = 7546;\n            b.value7547 = 7547;\n            b.value7548 = 7548;\n            b.value7549 = 7549;\n            b.value7550 = 7550;\n            b.value7551 = 7551;\n            b.value7552 = 7552;\n            b.value7553 = 7553;\n            b.value7554 = 7554;\n            b.value7555 = 7555;\n            b.value7556 = 7556;\n            b.value7557 = 7557;\n            b.value7558 = 7558;\n            b.value7559 = 7559;\n            b.value7560 = 7560;\n            b.value7561 = 7561;\n            b.value7562 = 7562;\n            b.value7563 = 7563;\n            b.value7564 = 7564;\n            b.value7565 = 7565;\n            b.value7566 = 7566;\n            b.value7567 = 7567;\n            b.value7568 = 7568;\n            b.value7569 = 7569;\n            b.value7570 = 7570;\n            b.value7571 = 7571;\n            b.value7572 = 7572;\n            b.value7573 = 7573;\n            b.value7574 = 7574;\n            b.value7575 = 7575;\n            b.value7576 = 7576;\n            b.value7577 = 7577;\n            b.value7578 = 7578;\n            b.value7579 = 7579;\n            b.value7580 = 7580;\n            b.value7581 = 7581;\n            b.value7582 = 7582;\n            b.value7583 = 7583;\n            b.value7584 = 7584;\n            b.value7585 = 7585;\n            b.value7586 = 7586;\n            b.value7587 = 7587;\n            b.value7588 = 7588;\n            b.value7589 = 7589;\n            b.value7590 = 7590;\n            b.value7591 = 7591;\n            b.value7592 = 7592;\n            b.value7593 = 7593;\n            b.value7594 = 7594;\n            b.value7595 = 7595;\n            b.value7596 = 7596;\n            b.value7597 = 7597;\n            b.value7598 = 7598;\n            b.value7599 = 7599;\n            b.value7600 = 7600;\n            b.value7601 = 7601;\n            b.value7602 = 7602;\n            b.value7603 = 7603;\n            b.value7604 = 7604;\n            b.value7605 = 7605;\n            b.value7606 = 7606;\n            b.value7607 = 7607;\n            b.value7608 = 7608;\n            b.value7609 = 7609;\n            b.value7610 = 7610;\n            b.value7611 = 7611;\n            b.value7612 = 7612;\n            b.value7613 = 7613;\n            b.value7614 = 7614;\n            b.value7615 = 7615;\n            b.value7616 = 7616;\n            b.value7617 = 7617;\n            b.value7618 = 7618;\n            b.value7619 = 7619;\n            b.value7620 = 7620;\n            b.value7621 = 7621;\n            b.value7622 = 7622;\n            b.value7623 = 7623;\n            b.value7624 = 7624;\n            b.value7625 = 7625;\n            b.value7626 = 7626;\n            b.value7627 = 7627;\n            b.value7628 = 7628;\n            b.value7629 = 7629;\n            b.value7630 = 7630;\n            b.value7631 = 7631;\n            b.value7632 = 7632;\n            b.value7633 = 7633;\n            b.value7634 = 7634;\n            b.value7635 = 7635;\n            b.value7636 = 7636;\n            b.value7637 = 7637;\n            b.value7638 = 7638;\n            b.value7639 = 7639;\n            b.value7640 = 7640;\n            b.value7641 = 7641;\n            b.value7642 = 7642;\n            b.value7643 = 7643;\n            b.value7644 = 7644;\n            b.value7645 = 7645;\n            b.value7646 = 7646;\n            b.value7647 = 7647;\n            b.value7648 = 7648;\n            b.value7649 = 7649;\n            b.value7650 = 7650;\n            b.value7651 = 7651;\n            b.value7652 = 7652;\n            b.value7653 = 7653;\n            b.value7654 = 7654;\n            b.value7655 = 7655;\n            b.value7656 = 7656;\n            b.value7657 = 7657;\n            b.value7658 = 7658;\n            b.value7659 = 7659;\n            b.value7660 = 7660;\n            b.value7661 = 7661;\n            b.value7662 = 7662;\n            b.value7663 = 7663;\n            b.value7664 = 7664;\n            b.value7665 = 7665;\n            b.value7666 = 7666;\n            b.value7667 = 7667;\n            b.value7668 = 7668;\n            b.value7669 = 7669;\n            b.value7670 = 7670;\n            b.value7671 = 7671;\n            b.value7672 = 7672;\n            b.value7673 = 7673;\n            b.value7674 = 7674;\n            b.value7675 = 7675;\n            b.value7676 = 7676;\n            b.value7677 = 7677;\n            b.value7678 = 7678;\n            b.value7679 = 7679;\n            b.value7680 = 7680;\n            b.value7681 = 7681;\n            b.value7682 = 7682;\n            b.value7683 = 7683;\n            b.value7684 = 7684;\n            b.value7685 = 7685;\n            b.value7686 = 7686;\n            b.value7687 = 7687;\n            b.value7688 = 7688;\n            b.value7689 = 7689;\n            b.value7690 = 7690;\n            b.value7691 = 7691;\n            b.value7692 = 7692;\n            b.value7693 = 7693;\n            b.value7694 = 7694;\n            b.value7695 = 7695;\n            b.value7696 = 7696;\n            b.value7697 = 7697;\n            b.value7698 = 7698;\n            b.value7699 = 7699;\n            b.value7700 = 7700;\n            b.value7701 = 7701;\n            b.value7702 = 7702;\n            b.value7703 = 7703;\n            b.value7704 = 7704;\n            b.value7705 = 7705;\n            b.value7706 = 7706;\n            b.value7707 = 7707;\n            b.value7708 = 7708;\n            b.value7709 = 7709;\n            b.value7710 = 7710;\n            b.value7711 = 7711;\n            b.value7712 = 7712;\n            b.value7713 = 7713;\n            b.value7714 = 7714;\n            b.value7715 = 7715;\n            b.value7716 = 7716;\n            b.value7717 = 7717;\n            b.value7718 = 7718;\n            b.value7719 = 7719;\n            b.value7720 = 7720;\n            b.value7721 = 7721;\n            b.value7722 = 7722;\n            b.value7723 = 7723;\n            b.value7724 = 7724;\n            b.value7725 = 7725;\n            b.value7726 = 7726;\n            b.value7727 = 7727;\n            b.value7728 = 7728;\n            b.value7729 = 7729;\n            b.value7730 = 7730;\n            b.value7731 = 7731;\n            b.value7732 = 7732;\n            b.value7733 = 7733;\n            b.value7734 = 7734;\n            b.value7735 = 7735;\n            b.value7736 = 7736;\n            b.value7737 = 7737;\n            b.value7738 = 7738;\n            b.value7739 = 7739;\n            b.value7740 = 7740;\n            b.value7741 = 7741;\n            b.value7742 = 7742;\n            b.value7743 = 7743;\n            b.value7744 = 7744;\n            b.value7745 = 7745;\n            b.value7746 = 7746;\n            b.value7747 = 7747;\n            b.value7748 = 7748;\n            b.value7749 = 7749;\n            b.value7750 = 7750;\n            b.value7751 = 7751;\n            b.value7752 = 7752;\n            b.value7753 = 7753;\n            b.value7754 = 7754;\n            b.value7755 = 7755;\n            b.value7756 = 7756;\n            b.value7757 = 7757;\n            b.value7758 = 7758;\n            b.value7759 = 7759;\n            b.value7760 = 7760;\n            b.value7761 = 7761;\n            b.value7762 = 7762;\n            b.value7763 = 7763;\n            b.value7764 = 7764;\n            b.value7765 = 7765;\n            b.value7766 = 7766;\n            b.value7767 = 7767;\n            b.value7768 = 7768;\n            b.value7769 = 7769;\n            b.value7770 = 7770;\n            b.value7771 = 7771;\n            b.value7772 = 7772;\n            b.value7773 = 7773;\n            b.value7774 = 7774;\n            b.value7775 = 7775;\n            b.value7776 = 7776;\n            b.value7777 = 7777;\n        }\n    }\n}\n\nListWrite.new(\"Attribute Write\").run();\n"
  },
  {
    "path": "microbenchmarks/enum_case.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nenum Foo { case A, case B }\n\nextension Foo {\n    type func get_case(x) {\n        if x {\n            return Foo::A;\n        } else {\n            return Foo::B;\n        }\n    }\n}\n\nfunc foo(_) {}\n\nstruct EnumCaseCreation : Microbenchmark {\n    func test() {\n        val which = true;\n        for _ in 0.to(100_000) {\n            foo(Foo.get_case(which));\n            which = !which;\n        }\n    }\n}\n\nEnumCaseCreation.new(\"Enum Case Creation\").run();\n"
  },
  {
    "path": "microbenchmarks/infra.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\n\nstruct Timer {\n    type func new(f) {\n        return alloc(This) {\n            .fn = f,\n            .samples = []\n        };\n    }\n\n    func run(n=1) {\n        val start = now();\n        for _ in 0.to(n) {\n            this.fn();\n        }\n        val end = now();\n        val duration = (end - start)/1000.0;\n        this.samples.append(duration);\n        return duration;\n    }\n\n    func average() {\n        if this.samples.len() == 0 {\n            return 0.0;\n        }\n        return this.samples.sum() / this.samples.len();\n    }\n\n    func percentile(p) {\n        val n = this.samples.len();\n        if n == 0 {\n            return 0.0;\n        }\n\n        val s = this.samples;\n        s.quicksort();\n\n        val idxf = (p / 100.0) * (n - 1);\n        val idx = idxf.int();\n        return s[idx];\n    }\n\n    func p50() {\n        return this.percentile(50.0);\n    }\n\n    func p99() {\n        return this.percentile(99.0);\n    }\n\n    func p999() {\n        return this.percentile(99.9);\n    }\n\n    func max() {\n        return this.samples.max();\n    }\n\n    func min() {\n        return this.samples.min();\n    }\n}\n\nstruct BenchmarkArguments {\n    type func new() {\n        val verbose = false;\n        val count = 100;\n\n        val args = cmdline_arguments();\n        val i = 0;\n        while i < args.len() {\n            if args[i] == \"--verbose\" {\n                verbose = true;\n            } elsif args[i] == \"--count\" && i + 1 < args.len() {\n                match Int.parse(args[i+1]) {\n                    case Ok(x) => {\n                        count = x;\n                    },\n                    case Err(e) => {\n                        println(\"Invalid count argument: {0}\".format(e));\n                    }\n                }\n                i += 1;\n            }\n\n            i += 1;\n        }\n\n        return Box(){.count, .verbose};\n    }\n}\n\n# include this mixin and provide a func test() to create a microbenchmark\nmixin Microbenchmark {\n    type func new(name) = alloc(This) { .name };\n\n    # override this if you need to prepare data before running the benchmark\n    func prepare() {}\n\n    # override this if you need to clean up after running the benchmark\n    func teardown() {}\n\n    func _iter(collect, verbose) {\n        this.prepare();\n        if collect {\n            val duration = this.timer.run();\n            if verbose {\n                println(\"{1} duration: {0:.3}s\".format(duration, this.name));\n            }\n        } else {\n            this.test();\n        }\n        this.teardown();\n    }\n\n    func run(n=Maybe::None) {\n        val args = BenchmarkArguments.new();\n        val count = n ?? args.count;\n        assert hasattr(this, \"test\");\n        if !hasattr(this, \"timer\") {\n            this.timer = Timer.new(this.test);\n        }\n\n        count += 10;\n        val ten = 10;\n\n        # and now do the real testing\n        for _ in 0.to(count) {\n            this._iter(ten == 0, ten == 0 && args.verbose);\n            if ten > 0 {\n                ten -= 1;\n            }\n        }\n\n        println(\"{0} min: {1:.3}s p50: {2:.3}s p99: {3:.3}s p999: {4:.3}s max: {5:.3}s\".format(\n            this.name,\n            this.timer.min()??,\n            this.timer.p50(),\n            this.timer.p99(),\n            this.timer.p999(),\n            this.timer.max()??\n        ));\n    }\n}\n"
  },
  {
    "path": "microbenchmarks/int_arith.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nstruct IntegerArithmetic : Microbenchmark {\n    func test() {\n        val n = 2;\n        val m = 1;\n        while n < 500_000_000_000 {\n            n = n + 2 * m + n / m;\n            m = m + 1;\n        }\n    }\n}\n\nIntegerArithmetic.new(\"Integer Arithmetic\").run();\n"
  },
  {
    "path": "microbenchmarks/list_filled.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nfunc foo(_) {}\n\nstruct ListFilled : Microbenchmark {\n    func test() {\n        foo(List.filled(false, 1_000_000));\n    }\n}\n\nListFilled.new(\"List Filled\").run();\n"
  },
  {
    "path": "microbenchmarks/list_from_closure.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nfunc foo(_) {}\n\nstruct ListFromClosure : Microbenchmark {\n    func test() {\n        foo(List.from_function(|_| => false, 1_000_000));\n    }\n}\n\nListFromClosure.new(\"List From Closure\").run();\n"
  },
  {
    "path": "microbenchmarks/list_read.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nfunc foo(_) {}\n\nstruct ListWrite : Microbenchmark {\n    func prepare() {\n        this.list = List.filled(false, 100000);\n    }\n    # no need for teardown since we recreate the list each time\n\n    func test() {\n        for n in this.list {\n            foo(n);\n        }\n    }\n}\n\nListWrite.new(\"List Read\").run();\n"
  },
  {
    "path": "microbenchmarks/list_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nstruct ListWrite : Microbenchmark {\n    func test() {\n        val l = [];\n        for i in 0.to(100000) {\n            l.append(i);\n        }\n    }\n}\n\nListWrite.new(\"List Write\").run();\n"
  },
  {
    "path": "microbenchmarks/map_loop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\nimport Microbenchmark from infra;\n\nstruct MapLoop : Microbenchmark {\n    func prepare() {\n        val m = Map.new();\n        for i in 0.to(12_000) {\n            m.set(i, i);\n        }\n        this.m = m;\n    }\n\n    func test() {\n        for item in this.m {\n            assert item.value == item.key;\n        }\n    }\n}\n\nMapLoop.new(\"Map Iterator\").run();\n"
  },
  {
    "path": "microbenchmarks/method_call.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\nstruct Foo {\n    func answer() = 42;\n}\n\nstruct MethodCall : Microbenchmark {\n    func prepare() {\n        this.foo = alloc(Foo);\n    }\n\n    func test() {\n        for i in 0.to(100_000) {\n            assert this.foo.answer() == 42;\n        }\n    }\n}\n\nMethodCall.new(\"Method Call\").run();\n"
  },
  {
    "path": "microbenchmarks/sieve.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\nimport Microbenchmark from infra;\n\n# Based on https://github.com/PlummersSoftwareLLC/Primes/blob/drag-race/PrimeWren/solution_1/primes.wren\n\nimport Map from aria.structures.map;\n\nval DICT = Map.new() {\n    [10] = 4,\n    [100] = 25,\n    [1000] = 168,\n    [10000] = 1229,\n    [100000] = 9592,\n    [1000000] = 78498,\n    [10000000] = 664579,\n    [100000000] = 5761455,\n    [1000000000] = 50847534,\n    [10000000000] = 455052511,\n};\n\nextension Int {\n    func sqrt() {\n        val x = this;\n        val y = (x + 1) / 2;\n\n        while y < x {\n            x = y;\n            y = (x + this / x) / 2;\n        }\n\n        return x;\n    }\n}\n\nstruct SieveImpl {\n    type func new(size: Int) = alloc(This) {\n        .size,\n        .bits = List.filled(false, size),\n    };\n\n    func run() {\n        val bits = this.bits;\n        val size = this.size;\n\n        val factor = 3;\n        val q = size.sqrt();\n\n        while factor <= q {\n            val num = factor;\n            while num < size {\n                if !bits[num] {\n                    factor = num;\n                    break;\n                }\n\n                num += 2;\n            }\n\n            val num2 = factor * factor;\n            while num2 < size {\n                bits[num2] = true;\n                num2 += factor * 2;\n            }\n\n            factor += 2;\n        }\n    }\n\n    func count_primes() {\n        val count = 1;\n        val num = 3;\n        while num < this.size {\n            if !this.bits[num] {\n                count += 1;\n            }\n            num += 2;\n        }\n\n        return count;\n    }\n\n    func validate() = DICT.contains(this.size) && DICT[this.size] == this.count_primes();\n}\n\nstruct Sieve : Microbenchmark {\n    func teardown() {\n        assert this.impl.validate();\n    }\n\n    func test() {\n        this.impl = SieveImpl.new(1000000);\n        this.impl.run();\n    }\n}\n\nSieve.new(\"Sieve of Eratosthenes\").run();\n"
  },
  {
    "path": "native-libs/file/Cargo.toml",
    "content": "[package]\nname = \"file-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_file\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\n"
  },
  {
    "path": "native-libs/file/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::function_attribs::{FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\nuse haxby_vm::{\n    builtins::VmGlobals,\n    error::{dylib_load::LoadResult, exception::VmException, vm_error::VmErrorReason},\n    frame::Frame,\n    runtime_module::RuntimeModule,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, list::List, object::Object,\n        opaque::OpaqueValue, structure::Struct,\n    },\n    symbol::Symbol,\n    vm::{self, RunloopExit},\n};\n\nuse std::{\n    cell::RefCell,\n    fs::{File, OpenOptions},\n    io::{Read, Seek, Write},\n    rc::Rc,\n};\n\nconst FILE_MODE_READ: i64 = 1;\nconst FILE_MODE_WRITE: i64 = 2;\nconst FILE_MODE_APPEND: i64 = 4;\nconst FILE_MODE_TRUNCATE: i64 = 8;\nconst FILE_MODE_NEED_NEW: i64 = 16;\n\nfn open_options_from_int(n: i64) -> OpenOptions {\n    let mut opts = OpenOptions::new();\n\n    if (n & FILE_MODE_READ) != 0 {\n        opts.read(true);\n    }\n\n    if (n & FILE_MODE_WRITE) != 0 {\n        opts.write(true);\n        if (n & FILE_MODE_NEED_NEW) != 0 {\n            opts.create_new(true);\n        } else {\n            opts.create(true);\n        }\n        if (n & FILE_MODE_TRUNCATE) != 0 {\n            opts.truncate(true);\n        }\n    }\n\n    if (n & FILE_MODE_APPEND) != 0 {\n        opts.append(true);\n        if (n & FILE_MODE_NEED_NEW) != 0 {\n            opts.create_new(true);\n        } else {\n            opts.create(true);\n        }\n        if (n & FILE_MODE_TRUNCATE) != 0 {\n            opts.truncate(true);\n        }\n    }\n\n    opts\n}\n\nstruct MutableFile {\n    file: RefCell<File>,\n}\n\nfn file_symbol(builtins: &VmGlobals) -> Result<Symbol, VmErrorReason> {\n    builtins\n        .lookup_symbol(\"__file\")\n        .ok_or(VmErrorReason::UnexpectedVmState)\n}\n\nfn mut_file_from_aria(\n    aria_file: &Object,\n    builtins: &VmGlobals,\n) -> Result<Rc<MutableFile>, VmErrorReason> {\n    let file_sym = file_symbol(builtins)?;\n    let rust_file_obj = aria_file\n        .read(builtins, file_sym)\n        .ok_or(VmErrorReason::UnexpectedVmState)?;\n    rust_file_obj\n        .as_opaque_concrete::<MutableFile>()\n        .ok_or(VmErrorReason::UnexpectedVmState)\n}\n\nfn throw_io_error(\n    the_struct: &Struct,\n    message: String,\n    builtins: &mut VmGlobals,\n) -> crate::vm::ExecutionResult<RunloopExit> {\n    let err_sym = builtins\n        .intern_symbol(\"IOError\")\n        .expect(\"too many symbols interned\");\n    let io_error =\n        the_struct.extract_field(builtins, err_sym, |f: RuntimeValue| f.as_struct().cloned())?;\n    let io_error = RuntimeValue::Object(Object::new(&io_error));\n    let message_sym = builtins\n        .intern_symbol(\"message\")\n        .expect(\"too many symbols interned\");\n    let _ = io_error.write_attribute(message_sym, RuntimeValue::String(message.into()), builtins);\n    Ok(RunloopExit::Exception(VmException::from_value(io_error)))\n}\n\n#[derive(Default)]\nstruct New {}\nimpl BuiltinFunctionImpl for New {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_struct = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_struct().cloned())?;\n        let the_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n        let the_mode = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_integer().cloned())?;\n\n        let opts = open_options_from_int(*the_mode.raw_value());\n        match opts.open(the_path.raw_value()) {\n            Ok(file) => {\n                let file = MutableFile {\n                    file: RefCell::new(file),\n                };\n                let file_obj = OpaqueValue::new(file);\n                let aria_file_obj = RuntimeValue::Object(Object::new(&the_struct));\n                let file_sym = vm\n                    .globals\n                    .intern_symbol(\"__file\")\n                    .expect(\"too many symbols interned\");\n                let _ = aria_file_obj.write_attribute(\n                    file_sym,\n                    RuntimeValue::Opaque(file_obj),\n                    &mut vm.globals,\n                );\n                frame.stack.push(aria_file_obj);\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => throw_io_error(\n                &the_struct,\n                format!(\"Failed to open file: {e}\"),\n                &mut vm.globals,\n            ),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"_new\"\n    }\n}\n\n#[derive(Default)]\nstruct Close {}\nimpl BuiltinFunctionImpl for Close {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let file_sym = file_symbol(&vm.globals)?;\n        let unit = vm.globals.create_unit_object()?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n        let _ = rust_file_obj.file.borrow_mut().flush();\n        aria_file.write(&mut vm.globals, file_sym, unit);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::zero()\n    }\n\n    fn name(&self) -> &str {\n        \"_close\"\n    }\n}\n\n#[derive(Default)]\nstruct ReadAll {}\nimpl BuiltinFunctionImpl for ReadAll {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n        let mut dest = String::new();\n        {\n            let mut file_ref = rust_file_obj.file.borrow_mut();\n            match file_ref.read_to_string(&mut dest) {\n                Ok(_) => {\n                    frame.stack.push(RuntimeValue::String(dest.into()));\n                    Ok(RunloopExit::Ok(()))\n                }\n                Err(e) => throw_io_error(\n                    aria_file.get_struct(),\n                    format!(\"Failed to read file: {e}\"),\n                    &mut vm.globals,\n                ),\n            }\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_read_all\"\n    }\n}\n\n#[derive(Default)]\nstruct ReadCount {}\nimpl BuiltinFunctionImpl for ReadCount {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let count = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_integer().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n\n        let mut bytes = vec![0u8; *count.raw_value() as usize];\n        {\n            let mut file_ref = rust_file_obj.file.borrow_mut();\n            match file_ref.read_exact(&mut bytes) {\n                Ok(_) => {\n                    let result = bytes\n                        .iter()\n                        .map(|&b| b as i64)\n                        .map(|n| RuntimeValue::Integer(n.into()))\n                        .collect::<Vec<_>>();\n                    let result = List::from(&result);\n\n                    frame.stack.push(RuntimeValue::List(result));\n                    Ok(RunloopExit::Ok(()))\n                }\n                Err(e) => throw_io_error(\n                    aria_file.get_struct(),\n                    format!(\"Failed to read file: {e}\"),\n                    &mut vm.globals,\n                ),\n            }\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_read_count\"\n    }\n}\n\n#[derive(Default)]\nstruct WriteStr {}\nimpl BuiltinFunctionImpl for WriteStr {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let text = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n\n        let mut rfo = rust_file_obj.file.borrow_mut();\n        match rfo.write(text.raw_value().as_bytes()) {\n            Ok(n) => {\n                frame.stack.push(RuntimeValue::Integer((n as i64).into()));\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => throw_io_error(\n                aria_file.get_struct(),\n                format!(\"Failed to write file: {e}\"),\n                &mut vm.globals,\n            ),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_write_str\"\n    }\n}\n\n#[derive(Default)]\nstruct GetPos {}\nimpl BuiltinFunctionImpl for GetPos {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n\n        let mut rfo = rust_file_obj.file.borrow_mut();\n\n        match rfo.stream_position() {\n            Ok(n) => {\n                frame.stack.push(RuntimeValue::Integer((n as i64).into()));\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => throw_io_error(\n                aria_file.get_struct(),\n                format!(\"Failed to get file position: {e}\"),\n                &mut vm.globals,\n            ),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_getpos\"\n    }\n}\n\n#[derive(Default)]\nstruct SetPos {}\nimpl BuiltinFunctionImpl for SetPos {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let offset = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_integer().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n\n        let mut rfo = rust_file_obj.file.borrow_mut();\n\n        match rfo.seek(std::io::SeekFrom::Start(*offset.raw_value() as u64)) {\n            Ok(n) => {\n                frame.stack.push(RuntimeValue::Integer((n as i64).into()));\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => throw_io_error(\n                aria_file.get_struct(),\n                format!(\"Failed to set file position: {e}\"),\n                &mut vm.globals,\n            ),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_setpos\"\n    }\n}\n\n#[derive(Default)]\nstruct GetSize {}\nimpl BuiltinFunctionImpl for GetSize {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n\n        let rfo = rust_file_obj.file.borrow_mut();\n\n        match rfo.metadata() {\n            Ok(m) => {\n                frame\n                    .stack\n                    .push(RuntimeValue::Integer((m.len() as i64).into()));\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => throw_io_error(\n                aria_file.get_struct(),\n                format!(\"Failed to flush file: {e}\"),\n                &mut vm.globals,\n            ),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_getsize\"\n    }\n}\n\n#[derive(Default)]\nstruct Flush {}\nimpl BuiltinFunctionImpl for Flush {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_file = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_file_obj = mut_file_from_aria(&aria_file, &vm.globals)?;\n\n        let mut rfo = rust_file_obj.file.borrow_mut();\n\n        match rfo.flush() {\n            Ok(_) => Ok(RunloopExit::Ok(())),\n            Err(e) => throw_io_error(\n                aria_file.get_struct(),\n                format!(\"Failed to flush file: {e}\"),\n                &mut vm.globals,\n            ),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_getsize\"\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    vm: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    match unsafe { (vm.as_mut(), module.as_ref()) } {\n        (Some(vm), Some(module)) => {\n            let file = match module.load_named_value(\"File\") {\n                Some(file) => file,\n                None => {\n                    return LoadResult::error(\"cannot find File\");\n                }\n            };\n\n            let file_struct = match file.as_struct() {\n                Some(file) => file,\n                None => {\n                    return LoadResult::error(\"File is not a struct\");\n                }\n            };\n\n            file_struct.insert_builtin::<New>(&mut vm.globals);\n            file_struct.insert_builtin::<Close>(&mut vm.globals);\n            file_struct.insert_builtin::<ReadAll>(&mut vm.globals);\n            file_struct.insert_builtin::<ReadCount>(&mut vm.globals);\n            file_struct.insert_builtin::<WriteStr>(&mut vm.globals);\n            file_struct.insert_builtin::<GetPos>(&mut vm.globals);\n            file_struct.insert_builtin::<SetPos>(&mut vm.globals);\n            file_struct.insert_builtin::<Flush>(&mut vm.globals);\n            file_struct.insert_builtin::<GetSize>(&mut vm.globals);\n\n            LoadResult::success()\n        }\n        _ => LoadResult::error(\"invalid file module\"),\n    }\n}\n"
  },
  {
    "path": "native-libs/network/Cargo.toml",
    "content": "[package]\nname = \"network-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_http\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\nreqwest = { version = \"0.13.1\", features = [\"blocking\"] }\n"
  },
  {
    "path": "native-libs/network/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::function_attribs::FUNC_IS_METHOD;\nuse haxby_vm::{\n    error::dylib_load::LoadResult,\n    runtime_module::RuntimeModule,\n    runtime_value::{RuntimeValue, list::List, object::Object},\n    vm::ExecutionResult,\n};\n\n#[derive(Default)]\nstruct RequestGet {}\nimpl haxby_vm::runtime_value::function::BuiltinFunctionImpl for RequestGet {\n    fn eval(\n        &self,\n        frame: &mut haxby_vm::frame::Frame,\n        vm: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<haxby_vm::vm::RunloopExit> {\n        let this = haxby_vm::builtins::VmGlobals::extract_arg(frame, |x| x.as_object().cloned())?;\n        let headers = haxby_vm::builtins::VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let url_sym = vm\n            .globals\n            .intern_symbol(\"url\")\n            .expect(\"too many symbols interned\");\n        let timeout_sym = vm\n            .globals\n            .intern_symbol(\"timeout\")\n            .expect(\"too many symbols interned\");\n        let response_sym = vm\n            .globals\n            .intern_symbol(\"Response\")\n            .expect(\"too many symbols interned\");\n        let error_sym = vm\n            .globals\n            .intern_symbol(\"Error\")\n            .expect(\"too many symbols interned\");\n        let status_code_sym = vm\n            .globals\n            .intern_symbol(\"status_code\")\n            .expect(\"too many symbols interned\");\n        let headers_sym = vm\n            .globals\n            .intern_symbol(\"headers\")\n            .expect(\"too many symbols interned\");\n        let content_sym = vm\n            .globals\n            .intern_symbol(\"content\")\n            .expect(\"too many symbols interned\");\n        let msg_sym = vm\n            .globals\n            .intern_symbol(\"msg\")\n            .expect(\"too many symbols interned\");\n\n        let this_url = this.extract_field(&vm.globals, url_sym, |field: RuntimeValue| {\n            field.as_string().cloned()\n        })?;\n        let this_timeout =\n            this.extract_field(&vm.globals, timeout_sym, |field: RuntimeValue| {\n                field.as_float().cloned()\n            })?;\n        let as_struct = this.get_struct();\n        let this_response =\n            as_struct.extract_field(&vm.globals, response_sym, |field: RuntimeValue| {\n                field.as_struct().cloned()\n            })?;\n        let this_error =\n            as_struct.extract_field(&vm.globals, error_sym, |field: RuntimeValue| {\n                field.as_struct().cloned()\n            })?;\n\n        let mut client = reqwest::blocking::Client::new()\n            .get(this_url.raw_value())\n            .timeout(std::time::Duration::from_secs_f64(\n                *this_timeout.raw_value(),\n            ));\n        for i in 0..headers.len() {\n            let header = headers.get_at(i).unwrap();\n            if let Some(list) = header.as_list()\n                && list.len() == 2\n            {\n                let key = list.get_at(0).unwrap();\n                let value = list.get_at(1).unwrap();\n                if let (Some(key), Some(value)) = (key.as_string(), value.as_string()) {\n                    client = client.header(key.raw_value(), value.raw_value());\n                }\n            }\n        }\n\n        match client.send() {\n            Ok(r) => {\n                let response_obj = RuntimeValue::Object(Object::new(&this_response));\n                let _ = response_obj.write_attribute(\n                    status_code_sym,\n                    haxby_vm::runtime_value::RuntimeValue::Integer(\n                        (r.status().as_u16() as i64).into(),\n                    ),\n                    &mut vm.globals,\n                );\n                let header_list = List::from(&[]);\n                for header in r.headers() {\n                    let header_kvp = List::from(&[\n                        RuntimeValue::String(header.0.as_str().into()),\n                        RuntimeValue::String(header.1.to_str().unwrap_or(\"<err>\").into()),\n                    ]);\n                    header_list.append(RuntimeValue::List(header_kvp));\n                }\n                let _ = response_obj.write_attribute(\n                    headers_sym,\n                    RuntimeValue::List(header_list),\n                    &mut vm.globals,\n                );\n                match r.text() {\n                    Ok(content) => {\n                        let _ = response_obj.write_attribute(\n                            content_sym,\n                            RuntimeValue::String(content.into()),\n                            &mut vm.globals,\n                        );\n                    }\n                    _ => {\n                        let error_obj = RuntimeValue::Object(Object::new(&this_error));\n                        let _ = error_obj.write_attribute(\n                            msg_sym,\n                            RuntimeValue::String(\"content is not a valid String\".into()),\n                            &mut vm.globals,\n                        );\n                        let result_err = vm.globals.create_result_err(error_obj)?;\n                        frame.stack.push(result_err);\n                        return ExecutionResult::Ok(haxby_vm::vm::RunloopExit::Ok(()));\n                    }\n                }\n\n                let result_ok = vm.globals.create_result_ok(response_obj.clone())?;\n\n                frame.stack.push(result_ok);\n                Ok(haxby_vm::vm::RunloopExit::Ok(()))\n            }\n            Err(e) => {\n                let error_obj = RuntimeValue::Object(Object::new(&this_error));\n                let _ = error_obj.write_attribute(\n                    msg_sym,\n                    RuntimeValue::String(e.to_string().into()),\n                    &mut vm.globals,\n                );\n                let result_err = vm.globals.create_result_err(error_obj)?;\n\n                frame.stack.push(result_err);\n                ExecutionResult::Ok(haxby_vm::vm::RunloopExit::Ok(()))\n            }\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_get\"\n    }\n}\n\n#[derive(Default)]\nstruct RequestPost {}\nimpl haxby_vm::runtime_value::function::BuiltinFunctionImpl for RequestPost {\n    fn eval(\n        &self,\n        frame: &mut haxby_vm::frame::Frame,\n        vm: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<haxby_vm::vm::RunloopExit> {\n        let this = haxby_vm::builtins::VmGlobals::extract_arg(frame, |x| x.as_object().cloned())?;\n        let headers = haxby_vm::builtins::VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let payload =\n            haxby_vm::builtins::VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n\n        let url_sym = vm\n            .globals\n            .intern_symbol(\"url\")\n            .expect(\"too many symbols interned\");\n        let timeout_sym = vm\n            .globals\n            .intern_symbol(\"timeout\")\n            .expect(\"too many symbols interned\");\n        let response_sym = vm\n            .globals\n            .intern_symbol(\"Response\")\n            .expect(\"too many symbols interned\");\n        let error_sym = vm\n            .globals\n            .intern_symbol(\"Error\")\n            .expect(\"too many symbols interned\");\n        let status_code_sym = vm\n            .globals\n            .intern_symbol(\"status_code\")\n            .expect(\"too many symbols interned\");\n        let headers_sym = vm\n            .globals\n            .intern_symbol(\"headers\")\n            .expect(\"too many symbols interned\");\n        let content_sym = vm\n            .globals\n            .intern_symbol(\"content\")\n            .expect(\"too many symbols interned\");\n        let msg_sym = vm\n            .globals\n            .intern_symbol(\"msg\")\n            .expect(\"too many symbols interned\");\n\n        let this_url = this.extract_field(&vm.globals, url_sym, |field: RuntimeValue| {\n            field.as_string().cloned()\n        })?;\n        let this_timeout =\n            this.extract_field(&vm.globals, timeout_sym, |field: RuntimeValue| {\n                field.as_float().cloned()\n            })?;\n        let as_struct = this.get_struct();\n        let this_response =\n            as_struct.extract_field(&vm.globals, response_sym, |field: RuntimeValue| {\n                field.as_struct().cloned()\n            })?;\n        let this_error =\n            as_struct.extract_field(&vm.globals, error_sym, |field: RuntimeValue| {\n                field.as_struct().cloned()\n            })?;\n\n        let mut client = reqwest::blocking::Client::new()\n            .post(this_url.raw_value())\n            .body(payload.raw_value().to_owned())\n            .timeout(std::time::Duration::from_secs_f64(\n                *this_timeout.raw_value(),\n            ));\n        for i in 0..headers.len() {\n            let header = headers.get_at(i).unwrap();\n            if let Some(list) = header.as_list()\n                && list.len() == 2\n            {\n                let key = list.get_at(0).unwrap();\n                let value = list.get_at(1).unwrap();\n                if let (Some(key), Some(value)) = (key.as_string(), value.as_string()) {\n                    client = client.header(key.raw_value(), value.raw_value());\n                }\n            }\n        }\n\n        match client.send() {\n            Ok(r) => {\n                let response_obj = RuntimeValue::Object(Object::new(&this_response));\n                let _ = response_obj.write_attribute(\n                    status_code_sym,\n                    haxby_vm::runtime_value::RuntimeValue::Integer(\n                        (r.status().as_u16() as i64).into(),\n                    ),\n                    &mut vm.globals,\n                );\n                let header_list = List::from(&[]);\n                for header in r.headers() {\n                    let header_kvp = List::from(&[\n                        RuntimeValue::String(header.0.as_str().into()),\n                        RuntimeValue::String(header.1.to_str().unwrap_or(\"<err>\").into()),\n                    ]);\n                    header_list.append(RuntimeValue::List(header_kvp));\n                }\n                let _ = response_obj.write_attribute(\n                    headers_sym,\n                    RuntimeValue::List(header_list),\n                    &mut vm.globals,\n                );\n                match r.text() {\n                    Ok(content) => {\n                        let _ = response_obj.write_attribute(\n                            content_sym,\n                            RuntimeValue::String(content.into()),\n                            &mut vm.globals,\n                        );\n                    }\n                    _ => {\n                        let error_obj = RuntimeValue::Object(Object::new(&this_error));\n                        let _ = error_obj.write_attribute(\n                            msg_sym,\n                            RuntimeValue::String(\"content is not a valid String\".into()),\n                            &mut vm.globals,\n                        );\n                        let result_err = vm.globals.create_result_err(error_obj)?;\n\n                        frame.stack.push(result_err);\n                        return ExecutionResult::Ok(haxby_vm::vm::RunloopExit::Ok(()));\n                    }\n                }\n\n                let result_ok = vm.globals.create_result_ok(response_obj.clone())?;\n\n                frame.stack.push(result_ok);\n                Ok(haxby_vm::vm::RunloopExit::Ok(()))\n            }\n            Err(e) => {\n                let error_obj = RuntimeValue::Object(Object::new(&this_error));\n                let _ = error_obj.write_attribute(\n                    msg_sym,\n                    RuntimeValue::String(e.to_string().into()),\n                    &mut vm.globals,\n                );\n                let result_err = vm.globals.create_result_err(error_obj)?;\n\n                frame.stack.push(result_err);\n                ExecutionResult::Ok(haxby_vm::vm::RunloopExit::Ok(()))\n            }\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"_post\"\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    vm: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    match unsafe { (vm.as_mut(), module.as_ref()) } {\n        (Some(vm), Some(module)) => {\n            let request = match module.load_named_value(\"Request\") {\n                Some(request) => request,\n                None => {\n                    return LoadResult::error(\"cannot find Request\");\n                }\n            };\n\n            let request = match request.as_struct() {\n                Some(request) => request,\n                None => {\n                    return LoadResult::error(\"Request is not a struct\");\n                }\n            };\n\n            request.insert_builtin::<RequestGet>(&mut vm.globals);\n            request.insert_builtin::<RequestPost>(&mut vm.globals);\n\n            LoadResult::success()\n        }\n        _ => LoadResult::error(\"invalid network module\"),\n    }\n}\n"
  },
  {
    "path": "native-libs/path/Cargo.toml",
    "content": "[package]\nname = \"path-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_path\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nglob = { version = \"0.3.3\" }\n\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\n\n"
  },
  {
    "path": "native-libs/path/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::function_attribs::{FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\nuse haxby_vm::{\n    builtins::{\n        VmGlobals,\n        native_iterator::{AriaNativeIterator, NativeIteratorImpl, create_iterator_struct},\n    },\n    error::{dylib_load::LoadResult, vm_error::VmErrorReason},\n    frame::Frame,\n    runtime_module::RuntimeModule,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, object::Object, opaque::OpaqueValue,\n    },\n    symbol::Symbol,\n    vm::{self, RunloopExit},\n};\n\nuse std::{cell::RefCell, path::PathBuf, rc::Rc, time::SystemTime};\n\nstruct MutablePath {\n    content: RefCell<std::path::PathBuf>,\n}\n\nfn new_from_path<P: AsRef<std::path::Path>>(\n    the_struct: &haxby_vm::runtime_value::structure::Struct,\n    the_path: P,\n    path_sym: Symbol,\n    builtins: &mut VmGlobals,\n) -> RuntimeValue {\n    let pb = PathBuf::from(the_path.as_ref());\n    let pb = MutablePath {\n        content: RefCell::new(pb),\n    };\n\n    let path_obj = OpaqueValue::new(pb);\n    RuntimeValue::Object(Object::new(the_struct).with_value(\n        builtins,\n        path_sym,\n        RuntimeValue::Opaque(path_obj),\n    ))\n}\n\nfn create_path_result_err(\n    path_struct: &haxby_vm::runtime_value::structure::Struct,\n    message: String,\n    vm: &mut vm::VirtualMachine,\n) -> Result<RuntimeValue, VmErrorReason> {\n    let error_sym = vm\n        .globals\n        .intern_symbol(\"Error\")\n        .expect(\"too many symbols interned\");\n    let path_error = path_struct.extract_field(&vm.globals, error_sym, |field: RuntimeValue| {\n        field.as_struct().cloned()\n    })?;\n\n    let path_error = RuntimeValue::Object(Object::new(&path_error));\n    let msg_sym = vm\n        .globals\n        .intern_symbol(\"msg\")\n        .expect(\"too many symbols interned\");\n    let _ = path_error.write_attribute(\n        msg_sym,\n        RuntimeValue::String(message.into()),\n        &mut vm.globals,\n    );\n\n    vm.globals.create_result_err(path_error)\n}\n\nfn mut_path_from_aria(\n    aria_object: &Object,\n    builtins: &VmGlobals,\n) -> Result<Rc<MutablePath>, VmErrorReason> {\n    let path_sym = builtins\n        .lookup_symbol(\"__path\")\n        .ok_or(VmErrorReason::UnexpectedVmState)?;\n    let rust_obj = aria_object\n        .read(builtins, path_sym)\n        .ok_or(VmErrorReason::UnexpectedVmState)?;\n    rust_obj\n        .as_opaque_concrete::<MutablePath>()\n        .ok_or(VmErrorReason::UnexpectedVmState)\n}\n\nfn path_symbol(vm: &mut vm::VirtualMachine) -> Symbol {\n    vm.globals\n        .intern_symbol(\"__path\")\n        .expect(\"too many symbols interned\")\n}\n\n#[derive(Default)]\nstruct New {}\nimpl BuiltinFunctionImpl for New {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let the_struct = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_struct().cloned())?;\n        let the_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let path_sym = path_symbol(vm);\n        frame.stack.push(new_from_path(\n            &the_struct,\n            the_path.raw_value(),\n            path_sym,\n            &mut vm.globals,\n        ));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_new\"\n    }\n}\n\nstruct PathBufAriaIterator {\n    iter: Box<dyn Iterator<Item = PathBuf>>,\n    the_struct: haxby_vm::runtime_value::structure::Struct,\n    path_sym: Symbol,\n}\n\nimpl AriaNativeIterator for PathBufAriaIterator {\n    type Item = RuntimeValue;\n\n    fn next(&mut self, vm: &mut crate::vm::VirtualMachine) -> Option<Self::Item> {\n        let next_pathbuf = self.iter.next()?;\n\n        let next_runtime_val = new_from_path(\n            &self.the_struct,\n            next_pathbuf,\n            self.path_sym,\n            &mut vm.globals,\n        );\n\n        Some(next_runtime_val)\n    }\n}\n\n#[derive(Default)]\nstruct Glob {}\nimpl BuiltinFunctionImpl for Glob {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let the_struct = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_struct().cloned())?;\n        let glob_expr = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n        let path_sym = path_symbol(vm);\n\n        let val = match glob::glob(glob_expr.raw_value()) {\n            Ok(path) => {\n                let iterator_sym = vm\n                    .globals\n                    .intern_symbol(\"Iterator\")\n                    .expect(\"too many symbols interned\");\n                let iterator_rv = the_struct\n                    .load_named_value(&vm.globals, iterator_sym)\n                    .ok_or(VmErrorReason::UnexpectedVmState)?;\n                let iterator_struct = iterator_rv\n                    .as_struct()\n                    .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n                let values = path.flatten();\n\n                let iterator = create_iterator_struct(\n                    iterator_struct,\n                    NativeIteratorImpl::new(PathBufAriaIterator {\n                        iter: Box::new(values),\n                        the_struct: the_struct.clone(),\n                        path_sym,\n                    }),\n                    &mut vm.globals,\n                );\n\n                vm.globals.create_result_ok(iterator)?\n            }\n            Err(e) => create_path_result_err(&the_struct, e.to_string(), vm)?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_glob\"\n    }\n}\n\n#[derive(Default)]\nstruct Cwd {}\nimpl BuiltinFunctionImpl for Cwd {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let the_struct = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_struct().cloned())?;\n\n        let cwd = std::env::current_dir().map_err(|_| VmErrorReason::UnexpectedVmState)?;\n\n        let path_sym = path_symbol(vm);\n        frame\n            .stack\n            .push(new_from_path(&the_struct, &cwd, path_sym, &mut vm.globals));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_cwd\"\n    }\n}\n\n#[derive(Default)]\nstruct Prettyprint {}\nimpl BuiltinFunctionImpl for Prettyprint {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n\n        match rfo.as_os_str().to_str() {\n            Some(s) => {\n                frame.stack.push(RuntimeValue::String(s.into()));\n                Ok(RunloopExit::Ok(()))\n            }\n            None => Err(VmErrorReason::UnexpectedVmState.into()),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"prettyprint\"\n    }\n}\n\n#[derive(Default)]\nstruct Append {}\nimpl BuiltinFunctionImpl for Append {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let the_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let mut rfo = rust_obj.content.borrow_mut();\n        rfo.push(the_path.raw_value());\n\n        frame.stack.push(vm.globals.create_unit_object()?);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_append\"\n    }\n}\n\n#[derive(Default)]\nstruct Pop {}\nimpl BuiltinFunctionImpl for Pop {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let mut rfo = rust_obj.content.borrow_mut();\n        rfo.pop();\n        frame.stack.push(RuntimeValue::Object(aria_object));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"pop\"\n    }\n}\n\n#[derive(Default)]\nstruct IsAbsolutePath {}\nimpl BuiltinFunctionImpl for IsAbsolutePath {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame\n            .stack\n            .push(RuntimeValue::Boolean((rfo.is_absolute()).into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"is_absolute\"\n    }\n}\n\n#[derive(Default)]\nstruct Exists {}\nimpl BuiltinFunctionImpl for Exists {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame\n            .stack\n            .push(RuntimeValue::Boolean((rfo.exists()).into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"exists\"\n    }\n}\n\n#[derive(Default)]\nstruct IsDirectory {}\nimpl BuiltinFunctionImpl for IsDirectory {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame\n            .stack\n            .push(RuntimeValue::Boolean((rfo.is_dir()).into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"is_directory\"\n    }\n}\n\n#[derive(Default)]\nstruct IsFile {}\nimpl BuiltinFunctionImpl for IsFile {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame\n            .stack\n            .push(RuntimeValue::Boolean((rfo.is_file()).into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"is_file\"\n    }\n}\n\n#[derive(Default)]\nstruct IsSymlink {}\nimpl BuiltinFunctionImpl for IsSymlink {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame\n            .stack\n            .push(RuntimeValue::Boolean((rfo.is_symlink()).into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"is_symlink\"\n    }\n}\n\n#[derive(Default)]\nstruct Canonical {}\nimpl BuiltinFunctionImpl for Canonical {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let path_sym = path_symbol(vm);\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        let val = match rfo.canonicalize() {\n            Ok(path) => {\n                let canonical_object =\n                    new_from_path(aria_object.get_struct(), &path, path_sym, &mut vm.globals);\n\n                vm.globals.create_result_ok(canonical_object)?\n            }\n            Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"new_canonical\"\n    }\n}\n\n#[derive(Default)]\nstruct Size {}\nimpl BuiltinFunctionImpl for Size {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        let val = match rfo.metadata() {\n            Ok(md) => vm\n                .globals\n                .create_result_ok(RuntimeValue::Integer((md.len() as i64).into()))?,\n            Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"size\"\n    }\n}\n\n#[derive(Default)]\nstruct CreatedTime {}\nimpl BuiltinFunctionImpl for CreatedTime {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        let val = match rfo.metadata() {\n            Ok(md) => match md.created() {\n                Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n                Ok(val) => {\n                    let val = val\n                        .duration_since(SystemTime::UNIX_EPOCH)\n                        .unwrap()\n                        .as_millis();\n                    vm.globals\n                        .create_result_ok(RuntimeValue::Integer((val as i64).into()))?\n                }\n            },\n            Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_when_created\"\n    }\n}\n\n#[derive(Default)]\nstruct AccessedTime {}\nimpl BuiltinFunctionImpl for AccessedTime {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        let val = match rfo.metadata() {\n            Ok(md) => match md.accessed() {\n                Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n                Ok(val) => {\n                    let val = val\n                        .duration_since(SystemTime::UNIX_EPOCH)\n                        .unwrap()\n                        .as_millis();\n                    vm.globals\n                        .create_result_ok(RuntimeValue::Integer((val as i64).into()))?\n                }\n            },\n            Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_when_accessed\"\n    }\n}\n\n#[derive(Default)]\nstruct ModifiedTime {}\nimpl BuiltinFunctionImpl for ModifiedTime {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        let val = match rfo.metadata() {\n            Ok(md) => match md.modified() {\n                Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n                Ok(val) => {\n                    let val = val\n                        .duration_since(SystemTime::UNIX_EPOCH)\n                        .unwrap()\n                        .as_millis();\n                    vm.globals\n                        .create_result_ok(RuntimeValue::Integer((val as i64).into()))?\n                }\n            },\n            Err(e) => create_path_result_err(aria_object.get_struct(), e.to_string(), vm)?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"_when_modified\"\n    }\n}\n\n#[derive(Default)]\nstruct Filename {}\nimpl BuiltinFunctionImpl for Filename {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        match rfo.file_name() {\n            Some(name) => {\n                let name = name.to_str().ok_or(VmErrorReason::UnexpectedVmState)?;\n                let val = vm\n                    .globals\n                    .create_maybe_some(RuntimeValue::String(name.into()))?;\n                frame.stack.push(val);\n            }\n            None => {\n                let val = vm.globals.create_maybe_none()?;\n                frame.stack.push(val);\n            }\n        }\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"get_filename\"\n    }\n}\n\n#[derive(Default)]\nstruct Extension {}\nimpl BuiltinFunctionImpl for Extension {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        match rfo.extension() {\n            Some(name) => {\n                let name = name.to_str().ok_or(VmErrorReason::UnexpectedVmState)?;\n                let val = vm\n                    .globals\n                    .create_maybe_some(RuntimeValue::String(name.into()))?;\n                frame.stack.push(val);\n            }\n            None => {\n                let val = vm.globals.create_maybe_none()?;\n                frame.stack.push(val);\n            }\n        }\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"get_extension\"\n    }\n}\n\n#[derive(Default)]\nstruct Entries {}\nimpl BuiltinFunctionImpl for Entries {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let path_sym = path_symbol(vm);\n\n        let aria_struct = aria_object.get_struct().clone();\n        let iterator_sym = vm\n            .globals\n            .intern_symbol(\"Iterator\")\n            .expect(\"too many symbols interned\");\n        let iterator_struct =\n            aria_struct.extract_field(&vm.globals, iterator_sym, |f: RuntimeValue| {\n                f.as_struct().cloned()\n            })?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n        let rfo = rust_obj.content.borrow_mut();\n\n        if let Ok(rd) = rfo.read_dir() {\n            let values = rd.flatten().map(|e| e.path());\n\n            let iterator = create_iterator_struct(\n                &iterator_struct,\n                NativeIteratorImpl::new(PathBufAriaIterator {\n                    iter: Box::new(values),\n                    the_struct: aria_struct.clone(),\n                    path_sym,\n                }),\n                &mut vm.globals,\n            );\n\n            frame.stack.push(iterator);\n        } else {\n            let iterator = create_iterator_struct(\n                &iterator_struct,\n                NativeIteratorImpl::empty(),\n                &mut vm.globals,\n            );\n            frame.stack.push(iterator);\n        }\n\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"entries\"\n    }\n}\n\n#[derive(Default)]\nstruct MakeDirectory {}\nimpl BuiltinFunctionImpl for MakeDirectory {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame.stack.push(RuntimeValue::Boolean(\n            std::fs::create_dir(rfo.as_path()).is_ok().into(),\n        ));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"mkdir\"\n    }\n}\n\n#[derive(Default)]\nstruct MakeDirectories {}\nimpl BuiltinFunctionImpl for MakeDirectories {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame.stack.push(RuntimeValue::Boolean(\n            std::fs::create_dir_all(rfo.as_path()).is_ok().into(),\n        ));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"mkdirs\"\n    }\n}\n\n#[derive(Default)]\nstruct RemoveDirectory {}\nimpl BuiltinFunctionImpl for RemoveDirectory {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame.stack.push(RuntimeValue::Boolean(\n            std::fs::remove_dir(rfo.as_path()).is_ok().into(),\n        ));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"rmdir\"\n    }\n}\n\n#[derive(Default)]\nstruct RemoveFile {}\nimpl BuiltinFunctionImpl for RemoveFile {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let aria_object = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let rust_obj = mut_path_from_aria(&aria_object, &vm.globals)?;\n\n        let rfo = rust_obj.content.borrow_mut();\n        frame.stack.push(RuntimeValue::Boolean(\n            std::fs::remove_file(rfo.as_path()).is_ok().into(),\n        ));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"erase\"\n    }\n}\n\n#[derive(Default)]\nstruct Copy {}\nimpl BuiltinFunctionImpl for Copy {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let this_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let other_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let this_path = mut_path_from_aria(&this_path, &vm.globals)?;\n        let other_path = mut_path_from_aria(&other_path, &vm.globals)?;\n\n        let this_path = this_path.content.borrow_mut();\n        let other_path = other_path.content.borrow_mut();\n\n        frame.stack.push(RuntimeValue::Boolean(\n            std::fs::copy(this_path.as_path(), other_path.as_path())\n                .is_ok()\n                .into(),\n        ));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_copy\"\n    }\n}\n\n#[derive(Default)]\nstruct CommonAncestor {}\nimpl BuiltinFunctionImpl for CommonAncestor {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let this_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let this_struct = this_path.get_struct();\n        let other_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let path_sym = path_symbol(vm);\n\n        let this_path = mut_path_from_aria(&this_path, &vm.globals)?;\n        let other_path = mut_path_from_aria(&other_path, &vm.globals)?;\n\n        let this_path = this_path.content.borrow_mut();\n        let other_path = other_path.content.borrow_mut();\n\n        let val = match this_path.ancestors().find(|p| other_path.starts_with(p)) {\n            Some(p) => {\n                let candidate = new_from_path(this_struct, p, path_sym, &mut vm.globals);\n                vm.globals.create_maybe_some(candidate)?\n            }\n            None => vm.globals.create_maybe_none()?,\n        };\n\n        frame.stack.push(val);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"common_ancestor\"\n    }\n}\n\n#[derive(Default)]\nstruct Equals {}\nimpl BuiltinFunctionImpl for Equals {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut vm::VirtualMachine,\n    ) -> vm::ExecutionResult<RunloopExit> {\n        let this_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let other_path = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let this_path = mut_path_from_aria(&this_path, &vm.globals)?;\n        let other_path = mut_path_from_aria(&other_path, &vm.globals)?;\n\n        let this_path = this_path.content.borrow_mut();\n        let other_path = other_path.content.borrow_mut();\n\n        frame\n            .stack\n            .push(RuntimeValue::Boolean((*this_path == *other_path).into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_op_impl_equals\"\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    vm: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    match unsafe { (vm.as_mut(), module.as_ref()) } {\n        (Some(vm), Some(module)) => {\n            let path = match module.load_named_value(\"Path\") {\n                Some(path) => path,\n                None => {\n                    return LoadResult::error(\"cannot find Path\");\n                }\n            };\n\n            let path_struct = match path.as_struct() {\n                Some(path) => path,\n                None => {\n                    return LoadResult::error(\"Path is not a struct\");\n                }\n            };\n\n            path_struct.insert_builtin::<New>(&mut vm.globals);\n            path_struct.insert_builtin::<Glob>(&mut vm.globals);\n            path_struct.insert_builtin::<Cwd>(&mut vm.globals);\n            path_struct.insert_builtin::<Prettyprint>(&mut vm.globals);\n            path_struct.insert_builtin::<Append>(&mut vm.globals);\n            path_struct.insert_builtin::<Pop>(&mut vm.globals);\n            path_struct.insert_builtin::<IsAbsolutePath>(&mut vm.globals);\n            path_struct.insert_builtin::<Exists>(&mut vm.globals);\n            path_struct.insert_builtin::<IsDirectory>(&mut vm.globals);\n            path_struct.insert_builtin::<IsSymlink>(&mut vm.globals);\n            path_struct.insert_builtin::<IsFile>(&mut vm.globals);\n            path_struct.insert_builtin::<Canonical>(&mut vm.globals);\n            path_struct.insert_builtin::<Size>(&mut vm.globals);\n            path_struct.insert_builtin::<Entries>(&mut vm.globals);\n            path_struct.insert_builtin::<Filename>(&mut vm.globals);\n            path_struct.insert_builtin::<Extension>(&mut vm.globals);\n            path_struct.insert_builtin::<CreatedTime>(&mut vm.globals);\n            path_struct.insert_builtin::<AccessedTime>(&mut vm.globals);\n            path_struct.insert_builtin::<ModifiedTime>(&mut vm.globals);\n            path_struct.insert_builtin::<MakeDirectories>(&mut vm.globals);\n            path_struct.insert_builtin::<MakeDirectory>(&mut vm.globals);\n            path_struct.insert_builtin::<RemoveDirectory>(&mut vm.globals);\n            path_struct.insert_builtin::<RemoveFile>(&mut vm.globals);\n            path_struct.insert_builtin::<Copy>(&mut vm.globals);\n            path_struct.insert_builtin::<CommonAncestor>(&mut vm.globals);\n            path_struct.insert_builtin::<Equals>(&mut vm.globals);\n\n            LoadResult::success()\n        }\n        _ => LoadResult::error(\"invalid path module\"),\n    }\n}\n"
  },
  {
    "path": "native-libs/platform/Cargo.toml",
    "content": "[package]\nname = \"platform-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_platform\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\n"
  },
  {
    "path": "native-libs/platform/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::function_attribs::{FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\nuse haxby_vm::{\n    builtins::VmGlobals, error::dylib_load::LoadResult, frame::Frame,\n    runtime_module::RuntimeModule, runtime_value::RuntimeValue,\n    runtime_value::function::BuiltinFunctionImpl, vm::RunloopExit,\n};\n\n#[allow(unused)]\nconst LINUX_CASE: usize = 0;\n#[allow(unused)]\nconst MACOS_CASE: usize = 1;\n#[allow(unused)]\nconst UNKNOWN_CASE: usize = 2;\n\n#[derive(Default)]\nstruct GetPlatformInfo {}\nimpl BuiltinFunctionImpl for GetPlatformInfo {\n    #[cfg(target_os = \"linux\")]\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<RunloopExit> {\n        use haxby_vm::{error::vm_error::VmErrorReason, runtime_value::object::Object};\n\n        let kernel_version = match std::fs::read_to_string(\"/proc/sys/kernel/osrelease\") {\n            Ok(ver) => ver.trim().to_string(),\n            Err(_) => String::from(\"unknown\"),\n        };\n\n        let platform_enum = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_enum().cloned())?;\n\n        let linux_platform_sym = vm\n            .globals\n            .intern_symbol(\"LinuxPlatform\")\n            .expect(\"too many symbols interned\");\n        let linux_info = platform_enum\n            .load_named_value(&vm.globals, linux_platform_sym)\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let linux_info = linux_info\n            .as_struct()\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let linux_info = RuntimeValue::Object(Object::new(linux_info));\n        let kernel_version_sym = vm\n            .globals\n            .intern_symbol(\"kernel_version\")\n            .expect(\"too many symbols interned\");\n        let _ = linux_info.write_attribute(\n            kernel_version_sym,\n            RuntimeValue::String(kernel_version.into()),\n            &mut vm.globals,\n        );\n\n        let linux_enum_instance = platform_enum\n            .make_value(LINUX_CASE, Some(linux_info))\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        frame\n            .stack\n            .push(RuntimeValue::EnumValue(linux_enum_instance));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    #[cfg(target_os = \"macos\")]\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<RunloopExit> {\n        use haxby_vm::{error::vm_error::VmErrorReason, runtime_value::object::Object};\n\n        // Get macOS version using `sw_vers -productVersion`\n        let mac_version = match std::process::Command::new(\"sw_vers\")\n            .arg(\"-productVersion\")\n            .output()\n        {\n            Ok(output) if output.status.success() => {\n                String::from_utf8_lossy(&output.stdout).trim().to_string()\n            }\n            _ => String::from(\"unknown\"),\n        };\n\n        let platform_enum = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_enum().cloned())?;\n\n        let mac_platform_sym = vm\n            .globals\n            .intern_symbol(\"macOSPlatform\")\n            .expect(\"too many symbols interned\");\n        let mac_info = platform_enum\n            .load_named_value(&vm.globals, mac_platform_sym)\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let mac_info = mac_info\n            .as_struct()\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let mac_info = RuntimeValue::Object(Object::new(mac_info));\n        let os_build_sym = vm\n            .globals\n            .intern_symbol(\"os_build\")\n            .expect(\"too many symbols interned\");\n        let _ = mac_info.write_attribute(\n            os_build_sym,\n            RuntimeValue::String(mac_version.into()),\n            &mut vm.globals,\n        );\n\n        let mac_enum_instance = platform_enum\n            .make_value(MACOS_CASE, Some(mac_info))\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        frame.stack.push(RuntimeValue::EnumValue(mac_enum_instance));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    #[cfg(not(any(target_os = \"linux\", target_os = \"macos\")))]\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<RunloopExit> {\n        use haxby_vm::{error::vm_error::VmErrorReason, runtime_value::object::Object};\n\n        let platform_enum = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_enum().clone())?;\n\n        let unknown_case = platform_enum\n            .get_idx_of_case(&vm.globals, \"Unknown\")\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        let unknown_enum_instance = platform_enum\n            .make_value(unknown_case, None)\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        frame\n            .stack\n            .push(RuntimeValue::EnumValue(unknown_enum_instance));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn name(&self) -> &str {\n        \"local\"\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    vm: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    match unsafe { (vm.as_mut(), module.as_ref()) } {\n        (Some(vm), Some(module)) => {\n            let platform = match module.load_named_value(\"Platform\") {\n                Some(platform) => platform,\n                None => {\n                    return LoadResult::error(\"cannot find Platform\");\n                }\n            };\n\n            let platform_enum = match platform.as_enum() {\n                Some(platform) => platform,\n                None => {\n                    return LoadResult::error(\"Platform is not an enum\");\n                }\n            };\n\n            platform_enum.insert_builtin::<GetPlatformInfo>(&mut vm.globals);\n\n            LoadResult::success()\n        }\n        _ => LoadResult::error(\"invalid platform module\"),\n    }\n}\n"
  },
  {
    "path": "native-libs/regex/Cargo.toml",
    "content": "[package]\nname = \"regex-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_regex\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\nregex = \"1.12.2\"\n"
  },
  {
    "path": "native-libs/regex/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::function_attribs::{FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\nuse haxby_vm::{\n    builtins::VmGlobals,\n    error::{dylib_load::LoadResult, exception::VmException, vm_error::VmErrorReason},\n    frame::Frame,\n    runtime_module::RuntimeModule,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, list::List, object::Object,\n        opaque::OpaqueValue, structure::Struct,\n    },\n    vm::{ExecutionResult, RunloopExit, VirtualMachine},\n};\n\nfn create_regex_error(\n    regex_struct: &Struct,\n    message: String,\n    builtins: &mut VmGlobals,\n) -> Result<RuntimeValue, VmErrorReason> {\n    let error_sym = builtins\n        .intern_symbol(\"Error\")\n        .expect(\"too many symbols interned\");\n    let regex_error = regex_struct\n        .load_named_value(builtins, error_sym)\n        .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n    let regex_error = regex_error\n        .as_struct()\n        .ok_or(VmErrorReason::UnexpectedType)?;\n\n    let regex_error = RuntimeValue::Object(Object::new(regex_error));\n    let msg_sym = builtins\n        .intern_symbol(\"msg\")\n        .expect(\"too many symbols interned\");\n    let _ = regex_error.write_attribute(msg_sym, RuntimeValue::String(message.into()), builtins);\n\n    Ok(regex_error)\n}\n\n#[derive(Default)]\nstruct New {}\nimpl BuiltinFunctionImpl for New {\n    fn eval(&self, frame: &mut Frame, vm: &mut VirtualMachine) -> ExecutionResult<RunloopExit> {\n        let the_struct = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_struct().cloned())?;\n        let the_pattern = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let rust_regex_obj = match regex::Regex::new(the_pattern.raw_value()) {\n            Ok(s) => s,\n            Err(e) => {\n                let err = create_regex_error(&the_struct, e.to_string(), &mut vm.globals);\n                return match err {\n                    Ok(s) => Ok(RunloopExit::Exception(VmException::from_value(s))),\n                    Err(e) => Err(e.into()),\n                };\n            }\n        };\n\n        let rust_regex_obj = OpaqueValue::new(rust_regex_obj);\n\n        let aria_regex_obj = RuntimeValue::Object(Object::new(&the_struct));\n        let pattern_impl_sym = vm\n            .globals\n            .intern_symbol(\"__pattern\")\n            .expect(\"too many symbols interned\");\n        let pattern_sym = vm\n            .globals\n            .intern_symbol(\"pattern\")\n            .expect(\"too many symbols interned\");\n        let _ = aria_regex_obj.write_attribute(\n            pattern_impl_sym,\n            RuntimeValue::Opaque(rust_regex_obj),\n            &mut vm.globals,\n        );\n        let _ = aria_regex_obj.write_attribute(\n            pattern_sym,\n            RuntimeValue::String(the_pattern),\n            &mut vm.globals,\n        );\n\n        frame.stack.push(aria_regex_obj);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"new\"\n    }\n}\n\n#[derive(Default)]\nstruct AnyMatch {}\nimpl BuiltinFunctionImpl for AnyMatch {\n    fn eval(&self, frame: &mut Frame, vm: &mut VirtualMachine) -> ExecutionResult<RunloopExit> {\n        let aria_regex = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let the_haystack = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let pattern_sym = vm\n            .globals\n            .lookup_symbol(\"__pattern\")\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let rust_regex_obj = match aria_regex.read(&vm.globals, pattern_sym) {\n            Some(s) => s,\n            None => return Err(VmErrorReason::UnexpectedVmState.into()),\n        };\n        let rust_regex_obj = match rust_regex_obj.as_opaque_concrete::<regex::Regex>() {\n            Some(s) => s,\n            None => return Err(VmErrorReason::UnexpectedVmState.into()),\n        };\n\n        let matches = rust_regex_obj.is_match(the_haystack.raw_value());\n\n        frame.stack.push(RuntimeValue::Boolean(matches.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"any_match\"\n    }\n}\n\n#[derive(Default)]\nstruct Matches {}\nimpl BuiltinFunctionImpl for Matches {\n    fn eval(&self, frame: &mut Frame, vm: &mut VirtualMachine) -> ExecutionResult<RunloopExit> {\n        let aria_regex = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n        let aria_struct = aria_regex.get_struct().clone();\n        let the_haystack = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let match_sym = vm\n            .globals\n            .intern_symbol(\"Match\")\n            .expect(\"too many symbols interned\");\n        let match_struct_type =\n            aria_struct.extract_field(&vm.globals, match_sym, |e: RuntimeValue| {\n                e.as_struct().cloned()\n            })?;\n\n        let pattern_sym = vm\n            .globals\n            .lookup_symbol(\"__pattern\")\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let rust_regex_obj = match aria_regex.read(&vm.globals, pattern_sym) {\n            Some(s) => s,\n            None => return Err(VmErrorReason::UnexpectedVmState.into()),\n        };\n        let rust_regex_obj = match rust_regex_obj.as_opaque_concrete::<regex::Regex>() {\n            Some(s) => s,\n            None => return Err(VmErrorReason::UnexpectedVmState.into()),\n        };\n\n        let matches: Vec<_> = rust_regex_obj\n            .find_iter(the_haystack.raw_value())\n            .map(|mh| (mh.start() as i64, mh.len() as i64, mh.as_str()))\n            .collect();\n\n        let matches_list = List::default();\n        let start_sym = vm\n            .globals\n            .intern_symbol(\"start\")\n            .expect(\"too many symbols interned\");\n        let len_sym = vm\n            .globals\n            .intern_symbol(\"len\")\n            .expect(\"too many symbols interned\");\n        let value_sym = vm\n            .globals\n            .intern_symbol(\"value\")\n            .expect(\"too many symbols interned\");\n        for m in matches {\n            let match_obj = RuntimeValue::Object(Object::new(&match_struct_type));\n            let _ = match_obj.write_attribute(\n                start_sym,\n                RuntimeValue::Integer(m.0.into()),\n                &mut vm.globals,\n            );\n            let _ = match_obj.write_attribute(\n                len_sym,\n                RuntimeValue::Integer(m.1.into()),\n                &mut vm.globals,\n            );\n            let _ = match_obj.write_attribute(\n                value_sym,\n                RuntimeValue::String(m.2.into()),\n                &mut vm.globals,\n            );\n            matches_list.append(match_obj);\n        }\n\n        frame.stack.push(RuntimeValue::List(matches_list));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"matches\"\n    }\n}\n\n#[derive(Default)]\nstruct Replace {}\nimpl BuiltinFunctionImpl for Replace {\n    fn eval(&self, frame: &mut Frame, vm: &mut VirtualMachine) -> ExecutionResult<RunloopExit> {\n        let aria_regex = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let the_haystack = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let new_value = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_string().cloned())?;\n\n        let pattern_sym = vm\n            .globals\n            .lookup_symbol(\"__pattern\")\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let rust_regex_obj = match aria_regex.read(&vm.globals, pattern_sym) {\n            Some(s) => s,\n            None => return Err(VmErrorReason::UnexpectedVmState.into()),\n        };\n        let rust_regex_obj = match rust_regex_obj.as_opaque_concrete::<regex::Regex>() {\n            Some(s) => s,\n            None => return Err(VmErrorReason::UnexpectedVmState.into()),\n        };\n\n        let target = rust_regex_obj\n            .replace_all(the_haystack.raw_value(), new_value.raw_value())\n            .to_string();\n\n        frame.stack.push(RuntimeValue::String(target.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"replace\"\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    vm: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    match unsafe { (vm.as_mut(), module.as_ref()) } {\n        (Some(vm), Some(module)) => {\n            let regex = match module.load_named_value(\"Regex\") {\n                Some(regex) => regex,\n                None => {\n                    return LoadResult::error(\"cannot find Regex\");\n                }\n            };\n\n            let regex = match regex.as_struct() {\n                Some(regex) => regex,\n                None => {\n                    return LoadResult::error(\"Regex is not a struct\");\n                }\n            };\n\n            regex.insert_builtin::<New>(&mut vm.globals);\n            regex.insert_builtin::<AnyMatch>(&mut vm.globals);\n            regex.insert_builtin::<Matches>(&mut vm.globals);\n            regex.insert_builtin::<Replace>(&mut vm.globals);\n\n            LoadResult::success()\n        }\n        _ => LoadResult::error(\"invalid regex module\"),\n    }\n}\n"
  },
  {
    "path": "native-libs/timezone/Cargo.toml",
    "content": "[package]\nname = \"timezone-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_timezone\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\nlibc = \"0.2.180\"\n"
  },
  {
    "path": "native-libs/timezone/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_vm::{\n    error::dylib_load::LoadResult,\n    runtime_module::RuntimeModule,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl, list::List},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct TimezoneInfo {}\nimpl BuiltinFunctionImpl for TimezoneInfo {\n    fn eval(\n        &self,\n        cur_frame: &mut haxby_vm::frame::Frame,\n        _: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<RunloopExit> {\n        let now = std::time::SystemTime::now()\n            .duration_since(std::time::UNIX_EPOCH)\n            .expect(\"before the epoch\")\n            .as_secs() as i64;\n\n        let mut tm = libc::tm {\n            tm_sec: 0,\n            tm_min: 0,\n            tm_hour: 0,\n            tm_mday: 0,\n            tm_mon: 0,\n            tm_year: 0,\n            tm_wday: 0,\n            tm_yday: 0,\n            tm_isdst: 0,\n            tm_gmtoff: 0,\n            tm_zone: std::ptr::null_mut(),\n        };\n        unsafe {\n            libc::localtime_r(&now, &mut tm);\n        }\n\n        let tm_zone_name = if tm.tm_zone.is_null() {\n            \"unknown\"\n        } else {\n            unsafe {\n                std::ffi::CStr::from_ptr(tm.tm_zone)\n                    .to_str()\n                    .unwrap_or(\"invalid\")\n            }\n        };\n\n        let resulting_object = List::from(&[]);\n        resulting_object.append(RuntimeValue::Integer((tm.tm_gmtoff / 60).into()));\n        resulting_object.append(RuntimeValue::String(tm_zone_name.to_string().into()));\n\n        cur_frame.stack.push(RuntimeValue::List(resulting_object));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::zero()\n    }\n\n    fn name(&self) -> &str {\n        \"tz_info\"\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    _: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    match unsafe { module.as_ref() } {\n        Some(module) => {\n            module.insert_builtin::<TimezoneInfo>();\n            LoadResult::success()\n        }\n        None => LoadResult::error(\"invalid platform module\"),\n    }\n}\n"
  },
  {
    "path": "native-libs/unicode/Cargo.toml",
    "content": "[package]\nname = \"unicode-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_unicode\"\npath = \"src/lib.rs\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nvm-lib = { path = \"../../vm-lib\" }\nopcodes-lib = { path = \"../../opcodes-lib\" }\nlibc = \"0.2.180\"\nunicode_categories = \"0.1.1\"\n"
  },
  {
    "path": "native-libs/unicode/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::BuiltinTypeId;\nuse haxby_vm::{\n    builtins::VmGlobals,\n    error::{dylib_load::LoadResult, vm_error::VmErrorReason},\n    runtime_module::RuntimeModule,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\nuse unicode_categories::UnicodeCategories;\n\ntrait CharFunctionImpl {\n    fn do_check(c: char) -> bool;\n    fn name() -> &'static str;\n}\n\nmacro_rules! make_char_fn {\n    ($name:ident, $method:ident) => {\n        #[allow(non_camel_case_types)]\n        #[derive(Default)]\n        struct $name {}\n\n        impl CharFunctionImpl for $name {\n            fn do_check(c: char) -> bool {\n                c.$method()\n            }\n\n            fn name() -> &'static str {\n                stringify!($name)\n            }\n        }\n    };\n}\n\nmake_char_fn!(is_lowercase_letter, is_letter_lowercase);\nmake_char_fn!(is_uppercase_letter, is_letter_uppercase);\nmake_char_fn!(is_digit, is_number);\nmake_char_fn!(is_whitespace, is_whitespace);\n\nstruct CharBuiltinFunction<T: CharFunctionImpl + Default> {\n    _marker: std::marker::PhantomData<T>,\n}\n\nimpl<T: CharFunctionImpl + Default> Default for CharBuiltinFunction<T> {\n    fn default() -> Self {\n        Self {\n            _marker: std::marker::PhantomData,\n        }\n    }\n}\n\nimpl<T: CharFunctionImpl + Default> BuiltinFunctionImpl for CharBuiltinFunction<T> {\n    fn eval(\n        &self,\n        cur_frame: &mut haxby_vm::frame::Frame,\n        _: &mut haxby_vm::vm::VirtualMachine,\n    ) -> haxby_vm::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(cur_frame, |x: RuntimeValue| x.as_string().cloned())?;\n        let this_raw = this.raw_value();\n        if let Some(char0) = this_raw.chars().next() {\n            let is = T::do_check(char0);\n            cur_frame.stack.push(RuntimeValue::Boolean(is.into()));\n            Ok(RunloopExit::Ok(()))\n        } else {\n            Err(VmErrorReason::IndexOutOfBounds(0).into())\n        }\n    }\n\n    fn arity(&self) -> haxby_vm::arity::Arity {\n        haxby_vm::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        T::name()\n    }\n}\n\n#[unsafe(no_mangle)]\n#[allow(clippy::not_unsafe_ptr_arg_deref)]\npub extern \"C\" fn dylib_haxby_inject(\n    vm: *mut haxby_vm::vm::VirtualMachine,\n    module: *const RuntimeModule,\n) -> LoadResult {\n    // the aria module isn't really useful here since it's just a placeholder to inject methods\n    // into the String builtin type, but I'd rather be safe here and check that it's also a valid\n    // module, not just a valid VM instance\n    if let (Some(vm), Some(_)) = unsafe { (vm.as_mut(), module.as_ref()) }\n        && let Some(string) = vm\n            .globals\n            .get_builtin_type_by_id(BuiltinTypeId::String)\n            .as_rust_native()\n    {\n        string.insert_builtin::<CharBuiltinFunction<is_lowercase_letter>>(&mut vm.globals);\n        string.insert_builtin::<CharBuiltinFunction<is_uppercase_letter>>(&mut vm.globals);\n        string.insert_builtin::<CharBuiltinFunction<is_digit>>(&mut vm.globals);\n        string.insert_builtin::<CharBuiltinFunction<is_whitespace>>(&mut vm.globals);\n        return LoadResult::success();\n    }\n\n    LoadResult::error(\"cannot inject class methods into String builtin\")\n}\n"
  },
  {
    "path": "opcodes-lib/Cargo.toml",
    "content": "[package]\nname = \"opcodes-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"haxby_opcodes\"\npath = \"src/lib.rs\"\n\n[dependencies]\nenum-as-inner = \"0.7.0\"\n"
  },
  {
    "path": "opcodes-lib/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub const OPCODE_NOP: u8 = 0;\npub const OPCODE_PUSH: u8 = 1;\npub const OPCODE_PUSH_0: u8 = 2;\npub const OPCODE_PUSH_1: u8 = 3;\npub const OPCODE_PUSH_TRUE: u8 = 4;\npub const OPCODE_PUSH_FALSE: u8 = 5;\npub const OPCODE_PUSH_BUILTIN_TYPE: u8 = 6;\npub const OPCODE_PUSH_RUNTIME_VALUE: u8 = 7;\npub const OPCODE_POP: u8 = 8;\npub const OPCODE_DUP: u8 = 9;\npub const OPCODE_SWAP: u8 = 10;\npub const OPCODE_COPY: u8 = 11;\n// ..\npub const OPCODE_ADD: u8 = 20;\npub const OPCODE_SUB: u8 = 21;\npub const OPCODE_MUL: u8 = 22;\npub const OPCODE_DIV: u8 = 23;\npub const OPCODE_REM: u8 = 24;\npub const OPCODE_NEG: u8 = 25;\npub const OPCODE_SHL: u8 = 26;\npub const OPCODE_SHR: u8 = 27;\n// ...\npub const OPCODE_READ_LOCAL: u8 = 30;\npub const OPCODE_WRITE_LOCAL: u8 = 31;\npub const OPCODE_TYPEDEF_LOCAL: u8 = 32;\npub const OPCODE_READ_NAMED: u8 = 33;\npub const OPCODE_WRITE_NAMED: u8 = 34;\npub const OPCODE_TYPEDEF_NAMED: u8 = 35;\npub const OPCODE_READ_INDEX: u8 = 36;\npub const OPCODE_WRITE_INDEX: u8 = 37;\npub const OPCODE_READ_ATTRIBUTE: u8 = 38;\npub const OPCODE_WRITE_ATTRIBUTE: u8 = 39;\npub const OPCODE_READ_UPLEVEL: u8 = 40;\n// ...\npub const OPCODE_EQ: u8 = 50;\npub const OPCODE_LT: u8 = 51;\npub const OPCODE_GT: u8 = 52;\npub const OPCODE_LTE: u8 = 53;\npub const OPCODE_GTE: u8 = 54;\npub const OPCODE_ISA: u8 = 55;\npub const OPCODE_LOGICAL_AND: u8 = 56;\npub const OPCODE_LOGICAL_OR: u8 = 57;\npub const OPCODE_XOR: u8 = 58;\npub const OPCODE_NOT: u8 = 59;\npub const OPCODE_BITWISE_AND: u8 = 60;\npub const OPCODE_BITWISE_OR: u8 = 61;\npub const OPCODE_JUMP: u8 = 62;\npub const OPCODE_JUMP_TRUE: u8 = 63;\npub const OPCODE_JUMP_FALSE: u8 = 64;\npub const OPCODE_JUMP_CONDITIONALLY: u8 = 65;\npub const OPCODE_JUMP_IF_ARG_SUPPLIED: u8 = 66;\n// ...\npub const OPCODE_TRY_ENTER: u8 = 72;\npub const OPCODE_TRY_EXIT: u8 = 73;\npub const OPCODE_THROW: u8 = 74;\npub const OPCODE_CALL: u8 = 75;\npub const OPCODE_RETURN: u8 = 76;\npub const OPCODE_RETURN_UNIT: u8 = 77;\n// ...\npub const OPCODE_BUILD_LIST: u8 = 80;\npub const OPCODE_BUILD_FUNCTION: u8 = 81;\npub const OPCODE_STORE_UPLEVEL: u8 = 82;\npub const OPCODE_BUILD_STRUCT: u8 = 83;\npub const OPCODE_BUILD_ENUM: u8 = 84;\npub const OPCODE_BUILD_MIXIN: u8 = 85;\npub const OPCODE_BIND_CASE: u8 = 87;\npub const OPCODE_INCLUDE_MIXIN: u8 = 88;\npub const OPCODE_NEW_ENUM_VAL: u8 = 89;\npub const OPCODE_ENUM_CHECK_IS_CASE: u8 = 90;\npub const OPCODE_ENUM_TRY_EXTRACT_PAYLOAD: u8 = 91;\npub const OPCODE_TRY_UNWRAP_PROTOCOL: u8 = 92;\n// ..\npub const OPCODE_READ_ATTRIBUTE_SYMBOL: u8 = 100;\npub const OPCODE_WRITE_ATTRIBUTE_SYMBOL: u8 = 101;\npub const OPCODE_NEW_ENUM_VAL_SYMBOL: u8 = 102;\npub const OPCODE_ENUM_CHECK_IS_CASE_SYMBOL: u8 = 103;\npub const OPCODE_BIND_CASE_SYMBOL: u8 = 104;\n// ...\npub const OPCODE_IMPORT: u8 = 250;\npub const OPCODE_LIFT_MODULE: u8 = 251;\npub const OPCODE_LOAD_DYLIB: u8 = 252;\npub const OPCODE_ASSERT: u8 = 253;\npub const OPCODE_HALT: u8 = 254;\n\n#[rustfmt::skip]\npub mod function_attribs {\n    pub const FUNC_IS_METHOD:            u8 = 1_u8 << 0;\n    pub const METHOD_ATTRIBUTE_TYPE:     u8 = 1_u8 << 1;\n    pub const FUNC_ACCEPTS_VARARG:       u8 = 1_u8 << 2;\n}\n\n#[allow(unused_imports)]\nuse function_attribs::*;\n\n#[repr(u8)]\n#[derive(Clone, Copy, PartialEq, Eq, enum_as_inner::EnumAsInner)]\npub enum BuiltinValueId {\n    ThisModule = 0,\n}\n\nimpl BuiltinValueId {\n    pub fn to_u8(&self) -> u8 {\n        *self as u8\n    }\n\n    pub fn name(&self) -> &'static str {\n        match self {\n            BuiltinValueId::ThisModule => \"ThisModule\",\n        }\n    }\n}\n\nimpl TryFrom<u8> for BuiltinValueId {\n    type Error = ();\n\n    fn try_from(value: u8) -> Result<Self, Self::Error> {\n        match value {\n            0 => Ok(BuiltinValueId::ThisModule),\n            _ => Err(()),\n        }\n    }\n}\n\n#[repr(u8)]\n#[derive(Clone, Copy, PartialEq, Eq, enum_as_inner::EnumAsInner)]\npub enum BuiltinTypeId {\n    Any = 0,\n    Module = 1,\n    Unit = 2,\n    Unimplemented = 3,\n    Maybe = 4,\n    Result = 5,\n    Int = 6,\n    String = 7,\n    RuntimeError = 8,\n    Bool = 9,\n    Float = 10,\n    List = 11,\n    Type = 12,\n}\n\nimpl BuiltinTypeId {\n    pub fn to_u8(&self) -> u8 {\n        *self as u8\n    }\n\n    pub fn last() -> Self {\n        BuiltinTypeId::Type\n    }\n\n    pub fn name(&self) -> &'static str {\n        match self {\n            BuiltinTypeId::Any => \"Any\",\n            BuiltinTypeId::Module => \"Module\",\n            BuiltinTypeId::Int => \"Int\",\n            BuiltinTypeId::List => \"List\",\n            BuiltinTypeId::String => \"String\",\n            BuiltinTypeId::Bool => \"Bool\",\n            BuiltinTypeId::Maybe => \"Maybe\",\n            BuiltinTypeId::Float => \"Float\",\n            BuiltinTypeId::Unimplemented => \"Unimplemented\",\n            BuiltinTypeId::RuntimeError => \"RuntimeError\",\n            BuiltinTypeId::Unit => \"Unit\",\n            BuiltinTypeId::Result => \"Result\",\n            BuiltinTypeId::Type => \"Type\",\n        }\n    }\n}\n\nimpl TryFrom<u8> for BuiltinTypeId {\n    type Error = ();\n\n    fn try_from(value: u8) -> Result<Self, Self::Error> {\n        match value {\n            0 => Ok(BuiltinTypeId::Any),\n            1 => Ok(BuiltinTypeId::Module),\n            2 => Ok(BuiltinTypeId::Unit),\n            3 => Ok(BuiltinTypeId::Unimplemented),\n            4 => Ok(BuiltinTypeId::Maybe),\n            5 => Ok(BuiltinTypeId::Result),\n            6 => Ok(BuiltinTypeId::Int),\n            7 => Ok(BuiltinTypeId::String),\n            8 => Ok(BuiltinTypeId::RuntimeError),\n            9 => Ok(BuiltinTypeId::Bool),\n            10 => Ok(BuiltinTypeId::Float),\n            11 => Ok(BuiltinTypeId::List),\n            12 => Ok(BuiltinTypeId::Type),\n            _ => Err(()),\n        }\n    }\n}\n\n#[rustfmt::skip]\npub mod enum_case_attribs {\n    pub const CASE_HAS_PAYLOAD:            u8 = 1_u8 << 0;\n}\n\n#[allow(unused_imports)]\nuse enum_case_attribs::*;\n\n#[rustfmt::skip]\npub mod try_unwrap_protocol_mode {\n    pub const PROPAGATE_ERROR:  u8 = 1;\n    pub const ASSERT_ERROR:     u8 = 2;\n    pub const FLAG_TO_CALLER:   u8 = 3;\n}\n\n#[allow(unused_imports)]\nuse try_unwrap_protocol_mode::*;\n\n#[derive(Clone, Copy)]\npub enum Opcode {\n    Nop,\n    Push(u16),\n    Push0,\n    Push1,\n    PushTrue,\n    PushFalse,\n    PushBuiltinTy(BuiltinTypeId),\n    PushRuntimeValue(BuiltinValueId),\n    Pop,\n    Dup,\n    Swap,\n    Copy(u8),\n    Add,\n    Sub,\n    Mul,\n    Div,\n    Rem,\n    Neg,\n    ShiftLeft,\n    ShiftRight,\n    Not,\n    Equal,\n    LessThan,\n    GreaterThan,\n    LessThanEqual,\n    GreaterThanEqual,\n    ReadLocal(u8),\n    WriteLocal(u8),\n    TypedefLocal(u8),\n    ReadNamed(u16),\n    WriteNamed(u16),\n    TypedefNamed(u16),\n    ReadIndex(u8),\n    WriteIndex(u8),\n    ReadAttribute(u16),\n    WriteAttribute(u16),\n    ReadAttributeSymbol(u32),\n    WriteAttributeSymbol(u32),\n    ReadUplevel(u8),\n    LogicalAnd,\n    LogicalOr,\n    Xor,\n    BitwiseAnd,\n    BitwiseOr,\n    JumpTrue(u16),\n    JumpFalse(u16),\n    Jump(u16),\n    JumpConditionally(u16, u16),\n    JumpIfArgSupplied(u8, u16),\n    Call(u8),\n    Return,\n    ReturnUnit,\n    TryEnter(u16),\n    TryExit,\n    Throw,\n    BuildList(u32),\n    BuildFunction,\n    StoreUplevel(u8),\n    BuildStruct,\n    BuildEnum,\n    BuildMixin,\n    BindCase(u8, u16),\n    BindCaseSymbol(u8, u32),\n    IncludeMixin,\n    NewEnumVal(u8, u16),\n    NewEnumValSymbol(u8, u32),\n    EnumCheckIsCase(u16),\n    EnumCheckIsCaseSymbol(u32),\n    EnumTryExtractPayload,\n    TryUnwrapProtocol(u8),\n    Isa,\n    Import(u16),\n    LiftModule,\n    LoadDylib(u16),\n    Assert(u16),\n    Halt,\n}\n\nimpl std::fmt::Display for Opcode {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Nop => write!(f, \"NOP\"),\n            Self::Push(arg0) => write!(f, \"PUSH @{arg0}\"),\n            Self::Push0 => write!(f, \"PUSH_0\"),\n            Self::Push1 => write!(f, \"PUSH_1\"),\n            Self::PushTrue => write!(f, \"PUSH_T\"),\n            Self::PushFalse => write!(f, \"PUSH_F\"),\n            Self::PushBuiltinTy(arg0) => write!(f, \"PUSH_BUILTIN_TY {}\", arg0.name()),\n            Self::PushRuntimeValue(arg0) => write!(f, \"PUSH_RUNTIME_VAL {}\", arg0.name()),\n            Self::Pop => write!(f, \"POP\"),\n            Self::Dup => write!(f, \"DUP\"),\n            Self::Swap => write!(f, \"SWAP\"),\n            Self::Copy(n) => write!(f, \"COPY -{n}\"),\n            Self::Add => write!(f, \"ADD\"),\n            Self::Sub => write!(f, \"SUB\"),\n            Self::Mul => write!(f, \"MUL\"),\n            Self::Div => write!(f, \"DIV\"),\n            Self::Rem => write!(f, \"REM\"),\n            Self::Equal => write!(f, \"EQ\"),\n            Self::Neg => write!(f, \"NEG\"),\n            Self::ShiftLeft => write!(f, \"SHL\"),\n            Self::ShiftRight => write!(f, \"SHR\"),\n            Self::Not => write!(f, \"NOT\"),\n            Self::ReadLocal(arg0) => write!(f, \"READ_LOCAL {arg0}\"),\n            Self::WriteLocal(arg0) => write!(f, \"WRITE_LOCAL {arg0}\"),\n            Self::TypedefLocal(arg0) => write!(f, \"TYPEDEF_LOCAL {arg0}\"),\n            Self::ReadNamed(arg0) => write!(f, \"READ_NAMED @{arg0}\"),\n            Self::WriteNamed(arg0) => write!(f, \"WRITE_NAMED @{arg0}\"),\n            Self::TypedefNamed(arg0) => write!(f, \"TYPEDEF_NAMED @{arg0}\"),\n            Self::ReadIndex(arg0) => write!(f, \"READ_INDEX {arg0}\"),\n            Self::WriteIndex(arg0) => write!(f, \"WRITE_INDEX {arg0}\"),\n            Self::ReadAttribute(arg0) => write!(f, \"READ_ATTRIB @{arg0}\"),\n            Self::WriteAttribute(arg0) => write!(f, \"WRITE_ATTRIB @{arg0}\"),\n            Self::ReadAttributeSymbol(arg0) => write!(f, \"READ_ATTRIB_SYM #{arg0}\"),\n            Self::WriteAttributeSymbol(arg0) => write!(f, \"WRITE_ATTRIB_SYM #{arg0}\"),\n            Self::ReadUplevel(arg0) => write!(f, \"READ_UPLEVEL {arg0}\"),\n            Self::LogicalAnd => write!(f, \"ANDL\"),\n            Self::LogicalOr => write!(f, \"ORL\"),\n            Self::Xor => write!(f, \"XOR\"),\n            Self::BitwiseAnd => write!(f, \"ANDB\"),\n            Self::BitwiseOr => write!(f, \"ORB\"),\n            Self::LessThan => write!(f, \"LT\"),\n            Self::GreaterThan => write!(f, \"GT\"),\n            Self::LessThanEqual => write!(f, \"LTE\"),\n            Self::GreaterThanEqual => write!(f, \"GTE\"),\n            Self::JumpTrue(arg0) => write!(f, \"JUMP_TRUE {arg0}\"),\n            Self::JumpFalse(arg0) => write!(f, \"JUMP_FALSE {arg0}\"),\n            Self::Jump(arg0) => write!(f, \"JUMP {arg0}\"),\n            Self::JumpConditionally(arg0, arg1) => write!(f, \"JUMP_CONDITIONALLY {arg0} {arg1}\"),\n            Self::JumpIfArgSupplied(arg0, arg1) => write!(f, \"JUMP_IF_ARG_SUPPLIED {arg0} {arg1}\"),\n            Self::Call(arg0) => write!(f, \"CALL {arg0}\"),\n            Self::Return => write!(f, \"RETURN\"),\n            Self::ReturnUnit => write!(f, \"RETURN_UNIT\"),\n            Self::TryEnter(arg0) => write!(f, \"ENTER_TRY {arg0}\"),\n            Self::TryExit => write!(f, \"EXIT_TRY\"),\n            Self::Throw => write!(f, \"THROW\"),\n            Self::BuildList(arg0) => write!(f, \"BUILD_LIST {arg0}\"),\n            Self::BuildFunction => write!(f, \"BUILD_FUNC\"),\n            Self::StoreUplevel(arg0) => write!(f, \"STORE_UPLEVEL {arg0}\"),\n            Self::BuildStruct => write!(f, \"BUILD_STRUCT\"),\n            Self::BuildEnum => write!(f, \"BUILD_ENUM\"),\n            Self::BuildMixin => write!(f, \"BUILD_MIXIN\"),\n            Self::BindCase(arg0, arg1) => write!(f, \"BIND_CASE {arg0} @{arg1}\"),\n            Self::BindCaseSymbol(arg0, arg1) => write!(f, \"BIND_CASE_SYM {arg0} #{arg1}\"),\n            Self::IncludeMixin => write!(f, \"INCLUDE_MIXIN\"),\n            Self::NewEnumVal(arg0, arg1) => write!(f, \"NEW_ENUM_VAL {arg0} @{arg1}\"),\n            Self::NewEnumValSymbol(arg0, arg1) => write!(f, \"NEW_ENUM_VAL_SYM {arg0} #{arg1}\"),\n            Self::EnumCheckIsCase(arg0) => write!(f, \"ENUM_CHECK_IS_CASE @{arg0}\"),\n            Self::EnumCheckIsCaseSymbol(arg0) => write!(f, \"ENUM_CHECK_IS_CASE_SYM #{arg0}\"),\n            Self::EnumTryExtractPayload => write!(f, \"ENUM_TRY_EXTRACT_PAYLOAD\"),\n            Self::TryUnwrapProtocol(mode) => write!(f, \"TRY_UNWRAP_PROTOCOL {mode}\"),\n            Self::Isa => write!(f, \"ISA\"),\n            Self::Import(arg0) => write!(f, \"IMPORT @{arg0}\"),\n            Self::LiftModule => write!(f, \"LIFT_MODULE\"),\n            Self::LoadDylib(arg0) => write!(f, \"LOAD_DYLIB @{arg0}\"),\n            Self::Assert(arg0) => write!(f, \"ASSERT @{arg0}\"),\n            Self::Halt => write!(f, \"HALT\"),\n        }\n    }\n}\n"
  },
  {
    "path": "package.sh",
    "content": "set -euo pipefail\n\nPROFILE=${PROFILE:-dist}\n\n# The authoritative copy of these variables is in .github/workflows/release.yml\nBIN_TARGETS=\"${BIN_TARGETS:-aria}\"\nDYLIB_CRATES=\"${DYLIB_CRATES:-aria_file aria_http aria_path aria_platform aria_regex aria_timezone}\"\nEXTRA_FILES=\"${EXTRA_FILES:-}\"\n\nNAME=\"aria\"\nVER=`awk '/^\\[package\\]/{p=1;next} /^\\[/{p=0}\n     p && $1==\"version\" {\n       if (match($0, /\"[^\"]+\"/)) {\n         v=substr($0, RSTART+1, RLENGTH-2) # strip quotes\n         print v\n         exit\n       }\n     }' aria-bin/Cargo.toml`\nTS=\"$(date -u +%Y%m%d%H%M%S)\"\n\nRUNOS=\"${RUNNER_OS:-$(uname -s)}\"\nHOST_TRIPLE=\"$(rustc -vV | sed -n 's/^host: //p')\"\n\nLIB_PREFIX=\"lib\"\nLIB_EXT=\"so\"\ncase \"$RUNOS\" in\n  macOS|Darwin)   LIB_PREFIX=\"lib\"; LIB_EXT=\"dylib\" ;;\n  Linux)   LIB_PREFIX=\"lib\"; LIB_EXT=\"so\" ;;\nesac\n\ncargo build --workspace --profile \"$PROFILE\"\nARIA_BUILD_CONFIG=${PROFILE} ./ci_tests.sh\n\nSTAGING_ROOT=\"$(mktemp -d)\"\ntrap 'rm -rf \"$STAGING_ROOT\"' EXIT\nARCHIVE_DIR=\"${NAME}-${VER}-${HOST_TRIPLE}\"\nDEST=\"$STAGING_ROOT/$ARCHIVE_DIR\"\n\nif [[ -n \"$BIN_TARGETS\" ]]; then\n  for b in $BIN_TARGETS; do\n    src=\"target/${PROFILE}/${b}\"\n    [[ -f \"$src\" ]] || { echo \"Missing binary: $src\" >&2; exit 2; }\n    mkdir -p \"$DEST/bin\"\n    cp -v \"$src\" \"$DEST/bin/\"\n  done\nelse\n  echo \"No binaries specified to be copied\" >&2; exit 2;\nfi\n\nif [[ -n \"$DYLIB_CRATES\" ]]; then\n  for c in $DYLIB_CRATES; do\n    libname=\"${LIB_PREFIX}${c}.${LIB_EXT}\"\n    src=\"target/${PROFILE}/${libname}\"\n    [[ -f \"$src\" ]] || { echo \"Missing cdylib: $src\" >&2; exit 3; }\n    mkdir -p \"$DEST/bin\"\n    cp -v \"$src\" \"$DEST/bin/\"\n  done\nfi\n\n[[ -d lib ]] && mkdir -p \"$DEST/lib\" && cp -a lib/. \"$DEST/lib/\"\n[[ -d examples ]] && mkdir -p \"$DEST/share/examples\" && cp -a examples/. \"$DEST/share/examples\"\n[[ -f docs/manual.md ]] && mkdir -p \"$DEST/share/docs\" && cp -a docs/manual.md \"$DEST/share/docs\"\n[[ -f docs/stdlib.md ]] && mkdir -p \"$DEST/share/docs\" && cp -a docs/stdlib.md \"$DEST/share/docs\"\n[[ -f docs/style_guide.md ]] && mkdir -p \"$DEST/share/docs\" && cp -a docs/style_guide.md \"$DEST/share/docs\"\n\nif [[ -n \"$EXTRA_FILES\" ]]; then\n  shopt -s nullglob dotglob\n  for f in $EXTRA_FILES; do\n    mkdir -p \"$DEST/bin\" \"$DEST/lib\" \"$DEST/share\"\n    [[ -e \"$f\" ]] || { echo \"Skipping missing: $f\" >&2; continue; }\n    cp -av \"$f\" \"$DEST/share/\"\n  done\n  shopt -u nullglob dotglob\nfi\n\nARCHIVE=\"${ARCHIVE_DIR}-${TS}.tgz\"\ntar -C \"$STAGING_ROOT\" -czf \"$ARCHIVE\" \"$ARCHIVE_DIR\"\n\nif command -v sha256sum >/dev/null 2>&1; then\n  sha256sum \"$ARCHIVE\" > \"${ARCHIVE}.sha256\"\nelif command -v shasum >/dev/null 2>&1; then\n  shasum -a 256 \"$ARCHIVE\" > \"${ARCHIVE}.sha256\"\nelif command -v certutil >/dev/null 2>&1; then\n  certutil -hashfile \"$ARCHIVE\" SHA256 | sed -n '1p' > \"${ARCHIVE}.sha256\"\nfi\n\necho \"Built: $ARCHIVE\"\n"
  },
  {
    "path": "parser-lib/Cargo.toml",
    "content": "[package]\nname = \"parser-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"aria_parser\"\npath = \"src/lib.rs\"\n\n[dependencies]\npest = \"2.8.5\"\npest_derive = \"2.8.5\"\n"
  },
  {
    "path": "parser-lib/src/ast/derive/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::grammar::Rule;\n\nuse super::SourceBuffer;\n\npub(super) trait Derive {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self\n    where\n        Self: Sized;\n}\n\n#[macro_export]\nmacro_rules! gen_from_components {\n    ( $rule:ident; $( $field:ident : $ty:ty ),* $(,)? ) => {\n        fn from_parse_tree(p: pest::iterators::Pair<'_, $crate::grammar::Rule>, source: &$crate::ast::SourceBuffer) -> Self {\n            assert!(p.as_rule() == $crate::grammar::Rule::$rule);\n            let loc = From::from(&p.as_span());\n            let mut inner = p.into_inner();\n            $(\n                let $field = <$ty>::from_parse_tree(\n                    inner.next().expect(concat!(\"need \", stringify!($field))),\n                    source\n                );\n            )*\n            Self {\n                loc: source.pointer(loc),\n                $( $field, )*\n            }\n        }\n    }\n}\n\n#[macro_export]\nmacro_rules! gen_from_options {\n    ($rule:ident; $(($variant_rule:ident, $variant_type:ident)),* $(,)?) => {\n        fn from_parse_tree(p: pest::iterators::Pair<'_, $crate::grammar::Rule>, source: &$crate::ast::SourceBuffer) -> Self {\n            assert!(p.as_rule() == $crate::grammar::Rule::$rule);\n            let mut inner = p.into_inner();\n            let next = inner.next().expect(\"need content\");\n            match next.as_rule() {\n                $($crate::grammar::Rule::$variant_rule => {\n                    Self::$variant_type($variant_type::from_parse_tree(next, source))\n                }),*\n                _ => panic!(\"invalid node\"),\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{fmt::Display, path::Path, rc::Rc};\n\nuse pest::{Parser, error::InputLocation};\n\nuse crate::grammar::{HaxbyParser, Rule};\n\nmod derive;\nmod nodes;\npub mod prettyprint;\n\n#[derive(Debug, Clone, PartialEq, Eq, Copy)]\npub struct Location {\n    pub start: usize,\n    pub stop: usize,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct SourceBuffer {\n    pub content: Rc<String>,\n    pub name: String,\n}\n\nimpl AsRef<str> for SourceBuffer {\n    fn as_ref(&self) -> &str {\n        self.content.as_ref()\n    }\n}\n\nimpl SourceBuffer {\n    pub fn stdin(input: &str) -> Self {\n        Self {\n            content: Rc::new(input.to_owned()),\n            name: String::from(\"<stdin>\"),\n        }\n    }\n\n    pub fn stdin_with_name(input: &str, name: &str) -> Self {\n        Self {\n            content: Rc::new(input.to_owned()),\n            name: String::from(name),\n        }\n    }\n\n    pub fn from_path(path: &Path) -> Result<Self, std::io::Error> {\n        let content = std::fs::read_to_string(path)?;\n        let path = match std::fs::canonicalize(path) {\n            Ok(cp) => cp.to_str().unwrap_or(\"<unknown>\").to_owned(),\n            Err(_) => \"<unknown>\".to_owned(),\n        };\n        Ok(Self {\n            content: Rc::new(content),\n            name: path,\n        })\n    }\n\n    pub fn file(path: &str) -> Result<Self, std::io::Error> {\n        let content = std::fs::read_to_string(path)?;\n        let path = match std::fs::canonicalize(path) {\n            Ok(cp) => match cp.to_str() {\n                Some(cps) => cps,\n                None => path,\n            }\n            .to_owned(),\n            Err(_) => path.to_owned(),\n        };\n        Ok(Self {\n            content: Rc::new(content),\n            name: path,\n        })\n    }\n\n    pub fn as_str(&self) -> String {\n        self.content.as_ref().to_owned()\n    }\n\n    pub fn pointer(&self, loc: Location) -> SourcePointer {\n        SourcePointer {\n            location: loc,\n            buffer: self.clone(),\n        }\n    }\n}\n\nimpl SourceBuffer {\n    pub fn lines(&self) -> Vec<String> {\n        self.content.lines().map(|x| x.to_owned()).collect()\n    }\n\n    pub fn indices_for_position(&self, pos: usize) -> (usize, usize) {\n        let start = self.content[..pos].rfind('\\n').map_or(0, |idx| idx + 1);\n        let end = self.content[pos..]\n            .find('\\n')\n            .map_or(self.content.len(), |idx| pos + idx);\n        (start, end)\n    }\n\n    pub fn line_for_position(&self, pos: usize) -> String {\n        let (start, end) = self.indices_for_position(pos);\n        self.content[start..end].to_owned()\n    }\n\n    pub fn line_index_for_position(&self, pos: usize) -> usize {\n        self.content[..pos].chars().filter(|&c| c == '\\n').count()\n    }\n\n    pub fn pointer_to_whole_buffer(&self) -> SourcePointer {\n        let start = 0;\n        let stop = self.content.len();\n        let loc = Location { start, stop };\n        self.pointer(loc)\n    }\n\n    pub fn pointer_to_last_line(&self) -> SourcePointer {\n        let (start, stop) = self.indices_for_position(self.content.len() - 1);\n        let loc = Location { start, stop };\n        self.pointer(loc)\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct SourcePointer {\n    pub location: Location,\n    pub buffer: SourceBuffer,\n}\n\nimpl Display for SourcePointer {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}:{}\",\n            self.buffer.name,\n            1 + self.buffer.line_index_for_position(self.location.start)\n        )\n    }\n}\n\nimpl<'i> From<&pest::Span<'i>> for Location {\n    fn from(value: &pest::Span<'i>) -> Self {\n        Self {\n            start: value.start(),\n            stop: value.end(),\n        }\n    }\n}\n\nimpl From<&InputLocation> for Location {\n    fn from(value: &InputLocation) -> Self {\n        match value {\n            InputLocation::Pos(pos) => Location {\n                start: *pos,\n                stop: *pos,\n            },\n            InputLocation::Span(span) => Location {\n                start: span.0,\n                stop: span.1,\n            },\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum IntLiteralBase {\n    Binary,\n    Octal,\n    Decimal,\n    Hexadecimal,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct IntLiteral {\n    pub loc: SourcePointer,\n    pub base: IntLiteralBase,\n    pub val: String,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct FloatLiteral {\n    pub loc: SourcePointer,\n    pub val: String,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct StringLiteral {\n    pub loc: SourcePointer,\n    pub value: String,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Identifier {\n    pub loc: SourcePointer,\n    pub value: String,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct IdentifierList {\n    pub loc: SourcePointer,\n    pub identifiers: Vec<Identifier>,\n}\n\nimpl IdentifierList {\n    pub fn empty(loc: SourcePointer) -> Self {\n        Self {\n            loc,\n            identifiers: vec![],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ExpressionList {\n    pub loc: SourcePointer,\n    pub expressions: Vec<Expression>,\n}\n\nimpl ExpressionList {\n    pub fn empty(loc: SourcePointer) -> Self {\n        Self {\n            loc,\n            expressions: vec![],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ListLiteral {\n    pub loc: SourcePointer,\n    pub items: ExpressionList,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ParenExpression {\n    pub loc: SourcePointer,\n    pub value: Box<Expression>,\n}\n\nimpl From<&Expression> for ParenExpression {\n    fn from(value: &Expression) -> Self {\n        Self {\n            loc: value.loc().clone(),\n            value: Box::new(value.clone()),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum Primary {\n    IntLiteral(IntLiteral),\n    FloatLiteral(FloatLiteral),\n    Identifier(Identifier),\n    ListLiteral(ListLiteral),\n    StringLiteral(StringLiteral),\n    ParenExpression(ParenExpression),\n}\n\nimpl Primary {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Self::IntLiteral(il) => &il.loc,\n            Self::FloatLiteral(fp) => &fp.loc,\n            Self::Identifier(id) => &id.loc,\n            Self::ListLiteral(ll) => &ll.loc,\n            Self::StringLiteral(sl) => &sl.loc,\n            Self::ParenExpression(pe) => &pe.loc,\n        }\n    }\n\n    pub fn is_int_literal(&self) -> bool {\n        matches!(self, Self::IntLiteral(_))\n    }\n\n    pub fn is_float_literal(&self) -> bool {\n        matches!(self, Self::FloatLiteral(_))\n    }\n\n    pub fn as_int_literal(&self) -> Option<&IntLiteral> {\n        if let Self::IntLiteral(il) = self {\n            Some(il)\n        } else {\n            None\n        }\n    }\n\n    pub fn as_float_literal(&self) -> Option<&FloatLiteral> {\n        if let Self::FloatLiteral(fl) = self {\n            Some(fl)\n        } else {\n            None\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermAttribute {\n    pub loc: SourcePointer,\n    pub id: Identifier,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermIndex {\n    pub loc: SourcePointer,\n    pub index: ExpressionList,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermCall {\n    pub loc: SourcePointer,\n    pub args: ExpressionList,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermEnumCase {\n    pub loc: SourcePointer,\n    pub id: Identifier,\n    pub payload: Option<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermFieldWrite {\n    pub loc: SourcePointer,\n    pub id: Identifier,\n    pub val: Option<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermIndexWrite {\n    pub loc: SourcePointer,\n    pub idx: ExpressionList,\n    pub val: Expression,\n}\n\n#[allow(clippy::large_enum_variant)]\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum PostfixTermWrite {\n    PostfixTermFieldWrite(PostfixTermFieldWrite),\n    PostfixTermIndexWrite(PostfixTermIndexWrite),\n}\n\nimpl PostfixTermWrite {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Self::PostfixTermFieldWrite(fw) => &fw.loc,\n            Self::PostfixTermIndexWrite(iw) => &iw.loc,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermWriteList {\n    pub loc: SourcePointer,\n    pub terms: Vec<PostfixTermWrite>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermObjectWrite {\n    pub loc: SourcePointer,\n    pub terms: PostfixTermWriteList,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum TryProtocolMode {\n    Return,\n    Assert,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixTermTryProtocol {\n    pub loc: SourcePointer,\n    pub mode: TryProtocolMode,\n}\n\n#[allow(clippy::large_enum_variant)]\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum PostfixTerm {\n    PostfixTermAttribute(PostfixTermAttribute),\n    PostfixTermIndex(PostfixTermIndex),\n    PostfixTermCall(PostfixTermCall),\n    PostfixTermObjectWrite(PostfixTermObjectWrite),\n    PostfixTermEnumCase(PostfixTermEnumCase),\n    PostfixTermTryProtocol(PostfixTermTryProtocol),\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixExpression {\n    pub loc: SourcePointer,\n    pub base: Primary,\n    pub terms: Vec<PostfixTerm>,\n}\n\nimpl PostfixExpression {\n    pub fn attrib_read(base: &Primary, name: &str) -> PostfixExpression {\n        let read_attr = PostfixTerm::PostfixTermAttribute(PostfixTermAttribute {\n            loc: base.loc().clone(),\n            id: Identifier {\n                loc: base.loc().clone(),\n                value: name.to_owned(),\n            },\n        });\n        Self {\n            loc: base.loc().clone(),\n            base: base.clone(),\n            terms: vec![read_attr],\n        }\n    }\n\n    pub fn method_call(base: &Primary, name: &str, args: &[Expression]) -> PostfixExpression {\n        let read_attr = PostfixTerm::PostfixTermAttribute(PostfixTermAttribute {\n            loc: base.loc().clone(),\n            id: Identifier {\n                loc: base.loc().clone(),\n                value: name.to_owned(),\n            },\n        });\n        let call_attr = PostfixTerm::PostfixTermCall(PostfixTermCall {\n            loc: base.loc().clone(),\n            args: ExpressionList {\n                loc: base.loc().clone(),\n                expressions: args.to_vec(),\n            },\n        });\n        Self {\n            loc: base.loc().clone(),\n            base: base.clone(),\n            terms: vec![read_attr, call_attr],\n        }\n    }\n}\n\nimpl From<&Primary> for PostfixExpression {\n    fn from(value: &Primary) -> Self {\n        Self {\n            loc: value.loc().clone(),\n            base: value.clone(),\n            terms: vec![],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct PostfixRvalue {\n    pub loc: SourcePointer,\n    pub expr: PostfixExpression,\n}\n\nimpl From<&PostfixExpression> for PostfixRvalue {\n    fn from(value: &PostfixExpression) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            expr: value.clone(),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Copy)]\npub enum UnarySymbol {\n    Exclamation,\n    Minus,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct UnaryOperation {\n    pub loc: SourcePointer,\n    pub operand: Option<UnarySymbol>,\n    pub postfix: PostfixRvalue,\n}\n\nimpl From<&PostfixRvalue> for UnaryOperation {\n    fn from(value: &PostfixRvalue) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            operand: None,\n            postfix: value.clone(),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum MulSymbol {\n    Star,\n    Slash,\n    Percent,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum AddSymbol {\n    Plus,\n    Minus,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum AddEqSymbol {\n    PlusEq,\n    MinusEq,\n    StarEq,\n    SlashEq,\n    PercentEq,\n    ShiftLeftEq,\n    ShiftRightEq,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MulOperation {\n    pub loc: SourcePointer,\n    pub left: UnaryOperation,\n    pub right: Vec<(MulSymbol, UnaryOperation)>,\n}\n\nimpl From<&UnaryOperation> for MulOperation {\n    fn from(value: &UnaryOperation) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            left: value.clone(),\n            right: vec![],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct AddOperation {\n    pub loc: SourcePointer,\n    pub left: MulOperation,\n    pub right: Vec<(AddSymbol, MulOperation)>,\n}\n\nimpl From<&MulOperation> for AddOperation {\n    fn from(value: &MulOperation) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            left: value.clone(),\n            right: vec![],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Copy)]\npub enum ShiftSymbol {\n    Leftward,\n    Rightward,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ShiftOperation {\n    pub loc: SourcePointer,\n    pub left: AddOperation,\n    pub right: Option<(ShiftSymbol, AddOperation)>,\n}\n\nimpl From<&AddOperation> for ShiftOperation {\n    fn from(value: &AddOperation) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            left: value.clone(),\n            right: None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Copy)]\npub enum RelSymbol {\n    Less,\n    LessEqual,\n    Greater,\n    GreaterEqual,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct RelOperation {\n    pub loc: SourcePointer,\n    pub left: ShiftOperation,\n    pub right: Option<(RelSymbol, ShiftOperation)>,\n}\n\nimpl From<&ShiftOperation> for RelOperation {\n    fn from(value: &ShiftOperation) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            left: value.clone(),\n            right: None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum CompSymbol {\n    Equal,\n    NotEqual,\n    Isa,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct CompOperation {\n    pub loc: SourcePointer,\n    pub left: RelOperation,\n    pub right: Option<(CompSymbol, RelOperation)>,\n}\n\nimpl From<&RelOperation> for CompOperation {\n    fn from(value: &RelOperation) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            left: value.clone(),\n            right: None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum LogSymbol {\n    Ampersand,\n    DoubleAmpersand,\n    DoublePipe,\n    Pipe,\n    Caret,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct LogOperation {\n    pub loc: SourcePointer,\n    pub left: CompOperation,\n    pub right: Vec<(LogSymbol, CompOperation)>,\n}\n\nimpl From<&CompOperation> for LogOperation {\n    fn from(value: &CompOperation) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            left: value.clone(),\n            right: vec![],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\n#[allow(clippy::large_enum_variant)]\npub enum LambdaBody {\n    Expression(Expression),\n    CodeBlock(CodeBlock),\n}\n\nimpl From<&LambdaBody> for FunctionBody {\n    fn from(value: &LambdaBody) -> Self {\n        match value {\n            LambdaBody::Expression(e) => {\n                let ret_stmt = ReturnStatement {\n                    loc: e.loc().clone(),\n                    val: Some(e.clone()),\n                };\n                Self {\n                    code: CodeBlock {\n                        loc: ret_stmt.loc.clone(),\n                        entries: vec![Statement::ReturnStatement(ret_stmt)],\n                    },\n                }\n            }\n            LambdaBody::CodeBlock(b) => Self { code: b.clone() },\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct LambdaFunction {\n    pub loc: SourcePointer,\n    pub args: ArgumentList,\n    pub body: Box<LambdaBody>,\n}\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct FunctionBody {\n    pub code: CodeBlock,\n}\n\nimpl FunctionBody {\n    pub fn loc(&self) -> &SourcePointer {\n        &self.code.loc\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct TernaryExpression {\n    pub loc: SourcePointer,\n    pub condition: Box<LogOperation>,\n    pub true_expression: Box<Expression>,\n    pub false_expression: Box<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct TryUnwrapExpression {\n    pub loc: SourcePointer,\n    pub left: Box<LogOperation>,\n    pub right: Box<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\n#[allow(clippy::large_enum_variant)]\npub enum Expression {\n    LambdaFunction(LambdaFunction),\n    LogOperation(LogOperation),\n    TernaryExpression(TernaryExpression),\n    TryUnwrapExpression(TryUnwrapExpression),\n}\n\nimpl From<&LogOperation> for Expression {\n    fn from(value: &LogOperation) -> Self {\n        Self::LogOperation(value.clone())\n    }\n}\n\nimpl From<&Identifier> for Expression {\n    fn from(value: &Identifier) -> Self {\n        let pfe = PostfixExpression::from(&Primary::Identifier(value.clone()));\n        Self::from(&pfe)\n    }\n}\n\nimpl From<&Primary> for Expression {\n    fn from(value: &Primary) -> Self {\n        let pfe = PostfixExpression::from(value);\n        Self::from(&pfe)\n    }\n}\n\nimpl From<&UnaryOperation> for Expression {\n    fn from(value: &UnaryOperation) -> Self {\n        Self::from(&LogOperation::from(&CompOperation::from(\n            &RelOperation::from(&ShiftOperation::from(&AddOperation::from(\n                &MulOperation::from(value),\n            ))),\n        )))\n    }\n}\n\nimpl From<&PostfixExpression> for Expression {\n    fn from(value: &PostfixExpression) -> Self {\n        Self::from(&LogOperation::from(&CompOperation::from(\n            &RelOperation::from(&ShiftOperation::from(&AddOperation::from(\n                &MulOperation::from(&UnaryOperation::from(&PostfixRvalue::from(value))),\n            ))),\n        )))\n    }\n}\n\nimpl Expression {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Expression::LogOperation(c) => &c.loc,\n            Expression::LambdaFunction(f) => &f.loc,\n            Expression::TernaryExpression(t) => &t.loc,\n            Expression::TryUnwrapExpression(t) => &t.loc,\n        }\n    }\n}\n\nimpl Expression {\n    pub fn call_function_passing_me(&self, func_name: &str) -> Expression {\n        let loc = self.loc().clone();\n\n        let func_ident = Identifier {\n            loc: loc.clone(),\n            value: func_name.to_owned(),\n        };\n\n        let base = Primary::Identifier(func_ident);\n\n        let args = ExpressionList {\n            loc: loc.clone(),\n            expressions: vec![self.clone()],\n        };\n\n        let call = PostfixTerm::PostfixTermCall(PostfixTermCall {\n            loc: loc.clone(),\n            args,\n        });\n\n        let pfe = PostfixExpression {\n            loc,\n            base,\n            terms: vec![call],\n        };\n\n        Expression::from(&pfe)\n    }\n\n    pub fn is_function_call(&self) -> (bool, Option<&str>) {\n        fn peel(log: &LogOperation) -> Option<&PostfixExpression> {\n            if !log.right.is_empty() {\n                return None;\n            }\n            let comp: &CompOperation = &log.left;\n            if comp.right.is_some() {\n                return None;\n            }\n            let rel: &RelOperation = &comp.left;\n            if rel.right.is_some() {\n                return None;\n            }\n            let shift: &ShiftOperation = &rel.left;\n            if shift.right.is_some() {\n                return None;\n            }\n            let add: &AddOperation = &shift.left;\n            if !add.right.is_empty() {\n                return None;\n            }\n            let mul: &MulOperation = &add.left;\n            if !mul.right.is_empty() {\n                return None;\n            }\n            let UnaryOperation { postfix, .. } = &mul.left;\n            Some(&postfix.expr)\n        }\n\n        fn resolve_name(pfe: &PostfixExpression) -> Option<&str> {\n            let last = pfe.terms.last()?;\n            if !matches!(last, PostfixTerm::PostfixTermCall(_)) {\n                return None;\n            }\n            if pfe.terms.len() == 1\n                && let crate::ast::Primary::Identifier(id) = &pfe.base\n            {\n                return Some(&id.value);\n            }\n            if pfe.terms.len() >= 2\n                && let PostfixTerm::PostfixTermAttribute(attr) = &pfe.terms[pfe.terms.len() - 2]\n            {\n                return Some(&attr.id.value);\n            }\n            None\n        }\n\n        match self {\n            Expression::LogOperation(log) => {\n                if let Some(pfe) = peel(log)\n                    && matches!(pfe.terms.last(), Some(PostfixTerm::PostfixTermCall(_)))\n                {\n                    return (true, resolve_name(pfe));\n                }\n                (false, None)\n            }\n            _ => (false, None),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct DeclarationId {\n    pub loc: SourcePointer,\n    pub name: Identifier,\n    pub ty: Option<Expression>,\n}\n\nimpl From<&Identifier> for DeclarationId {\n    fn from(value: &Identifier) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            name: value.clone(),\n            ty: None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ExpressionStatement {\n    pub loc: SourcePointer,\n    pub val: Option<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ValDeclEntry {\n    pub loc: SourcePointer,\n    pub id: DeclarationId,\n    pub val: Expression,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ValDeclStatement {\n    pub loc: SourcePointer,\n    pub decls: Vec<ValDeclEntry>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct AssignStatement {\n    pub loc: SourcePointer,\n    pub id: Vec<PostfixExpression>,\n    pub val: Vec<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct WriteOpEqStatement {\n    pub loc: SourcePointer,\n    pub id: PostfixExpression,\n    pub op: AddEqSymbol,\n    pub val: Expression,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct IfCondPiece {\n    pub loc: SourcePointer,\n    pub expression: Box<Expression>,\n    pub then: CodeBlock,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ElsePiece {\n    pub loc: SourcePointer,\n    pub then: CodeBlock,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ElsifPiece {\n    pub content: IfCondPiece,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct IfPiece {\n    pub content: IfCondPiece,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct IfStatement {\n    pub loc: SourcePointer,\n    pub iff: IfPiece,\n    pub elsif: Vec<ElsifPiece>,\n    pub els: Option<ElsePiece>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MatchPatternComp {\n    pub loc: SourcePointer,\n    pub op: CompSymbol,\n    pub expr: Expression,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MatchPatternRel {\n    pub loc: SourcePointer,\n    pub op: RelSymbol,\n    pub expr: Expression,\n}\n\nimpl MatchPatternComp {\n    pub fn isa(loc: SourcePointer, expr: Expression) -> Self {\n        Self {\n            loc,\n            op: CompSymbol::Isa,\n            expr,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MatchPatternEnumCase {\n    pub loc: SourcePointer,\n    pub case: Identifier,\n    pub payload: Option<DeclarationId>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum MatchPattern {\n    MatchPatternComp(MatchPatternComp),\n    MatchPatternRel(MatchPatternRel),\n    MatchPatternEnumCase(MatchPatternEnumCase),\n}\n\nimpl MatchPattern {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Self::MatchPatternComp(e) => &e.loc,\n            Self::MatchPatternRel(e) => &e.loc,\n            Self::MatchPatternEnumCase(c) => &c.loc,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MatchRule {\n    pub loc: SourcePointer,\n    pub patterns: Vec<MatchPattern>,\n    pub then: CodeBlock,\n}\n\nimpl MatchRule {\n    pub fn enum_and_case(\n        loc: SourcePointer,\n        enumm: &str,\n        case: &str,\n        payload: Option<Identifier>,\n        then: CodeBlock,\n    ) -> Self {\n        let enumm = Identifier {\n            loc: loc.clone(),\n            value: enumm.to_owned(),\n        };\n        let case = Identifier {\n            loc: loc.clone(),\n            value: case.to_owned(),\n        };\n        let payload = payload.map(|p| DeclarationId::from(&p));\n        let case_pattern = MatchPattern::MatchPatternEnumCase(MatchPatternEnumCase {\n            loc: enumm.loc.clone(),\n            case,\n            payload,\n        });\n        let isa_pattern = MatchPattern::MatchPatternComp(MatchPatternComp {\n            loc: loc.clone(),\n            op: CompSymbol::Isa,\n            expr: From::from(&enumm),\n        });\n        Self {\n            loc,\n            patterns: vec![isa_pattern, case_pattern],\n            then,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MatchStatement {\n    pub loc: SourcePointer,\n    pub expr: Expression,\n    pub rules: Vec<MatchRule>,\n    pub els: Option<ElsePiece>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct WhileStatement {\n    pub loc: SourcePointer,\n    pub cond: Expression,\n    pub then: CodeBlock,\n    pub els: Option<ElsePiece>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ForStatement {\n    pub loc: SourcePointer,\n    pub id: Identifier,\n    pub expr: Expression,\n    pub then: CodeBlock,\n    pub els: Option<ElsePiece>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ReturnStatement {\n    pub loc: SourcePointer,\n    pub val: Option<Expression>,\n}\n\nimpl From<&Expression> for ReturnStatement {\n    fn from(val: &Expression) -> Self {\n        Self {\n            loc: val.loc().clone(),\n            val: Some(val.clone()),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ThrowStatement {\n    pub loc: SourcePointer,\n    pub val: Expression,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct AssertStatement {\n    pub loc: SourcePointer,\n    pub val: Expression,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct BreakStatement {\n    pub loc: SourcePointer,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ContinueStatement {\n    pub loc: SourcePointer,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct TryBlock {\n    pub loc: SourcePointer,\n    pub body: CodeBlock,\n    pub id: Identifier,\n    pub catch: CodeBlock,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\n#[allow(clippy::large_enum_variant)]\npub enum Statement {\n    ValDeclStatement(ValDeclStatement),\n    AssignStatement(AssignStatement),\n    WriteOpEqStatement(WriteOpEqStatement),\n    IfStatement(IfStatement),\n    MatchStatement(MatchStatement),\n    WhileStatement(WhileStatement),\n    ForStatement(ForStatement),\n    CodeBlock(CodeBlock),\n    ReturnStatement(ReturnStatement),\n    ThrowStatement(ThrowStatement),\n    TryBlock(TryBlock),\n    AssertStatement(AssertStatement),\n    ExpressionStatement(ExpressionStatement),\n    BreakStatement(BreakStatement),\n    ContinueStatement(ContinueStatement),\n    StructDecl(StructDecl),\n    EnumDecl(EnumDecl),\n    FunctionDecl(FunctionDecl),\n}\n\nimpl Statement {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Self::ValDeclStatement(a) => &a.loc,\n            Self::AssignStatement(a) => &a.loc,\n            Self::WriteOpEqStatement(a) => &a.loc,\n            Self::IfStatement(a) => &a.loc,\n            Self::MatchStatement(a) => &a.loc,\n            Self::WhileStatement(a) => &a.loc,\n            Self::ForStatement(a) => &a.loc,\n            Self::CodeBlock(a) => &a.loc,\n            Self::ReturnStatement(a) => &a.loc,\n            Self::ThrowStatement(a) => &a.loc,\n            Self::TryBlock(a) => &a.loc,\n            Self::AssertStatement(a) => &a.loc,\n            Self::ExpressionStatement(a) => &a.loc,\n            Self::BreakStatement(a) => &a.loc,\n            Self::ContinueStatement(a) => &a.loc,\n            Self::StructDecl(s) => &s.loc,\n            Self::EnumDecl(e) => &e.loc,\n            Self::FunctionDecl(f) => &f.loc,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct CodeBlock {\n    pub loc: SourcePointer,\n    pub entries: Vec<Statement>,\n}\n\nimpl From<&Statement> for CodeBlock {\n    fn from(value: &Statement) -> Self {\n        Self {\n            loc: value.loc().clone(),\n            entries: vec![value.clone()],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ArgumentDecl {\n    pub loc: SourcePointer,\n    pub id: DeclarationId,\n    pub deft: Option<Expression>,\n}\n\nimpl ArgumentDecl {\n    pub fn name(&self) -> &String {\n        &self.id.name.value\n    }\n\n    pub fn type_info(&self) -> Option<&Expression> {\n        self.id.ty.as_ref()\n    }\n}\n\nimpl From<&DeclarationId> for ArgumentDecl {\n    fn from(value: &DeclarationId) -> Self {\n        Self {\n            loc: value.loc.clone(),\n            id: value.clone(),\n            deft: None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ArgumentList {\n    pub loc: SourcePointer,\n    pub names: Vec<ArgumentDecl>,\n    pub vararg: bool,\n}\n\nimpl ArgumentList {\n    pub fn empty(loc: SourcePointer) -> Self {\n        Self {\n            loc,\n            names: vec![],\n            vararg: false,\n        }\n    }\n\n    pub fn len(&self) -> usize {\n        self.names.len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.names.is_empty()\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct FunctionDecl {\n    pub loc: SourcePointer,\n    pub name: Identifier,\n    pub args: ArgumentList,\n    pub body: FunctionBody,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum MethodAccess {\n    Instance,\n    Type,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MethodDecl {\n    pub loc: SourcePointer,\n    pub access: MethodAccess,\n    pub name: Identifier,\n    pub args: ArgumentList,\n    pub body: FunctionBody,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum OperatorSymbol {\n    Plus,\n    Minus,\n    UnaryMinus,\n    Star,\n    Slash,\n    Percent,\n    LeftShift,\n    RightShift,\n    Equals,\n    LessThanEqual,\n    GreaterThanEqual,\n    LessThan,\n    GreaterThan,\n    BitwiseAnd,\n    BitwiseOr,\n    BitwiseXor,\n    Call,\n    GetSquareBrackets,\n    SetSquareBrackets,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct OperatorDecl {\n    pub loc: SourcePointer,\n    pub reverse: bool,\n    pub symbol: OperatorSymbol,\n    pub args: ArgumentList,\n    pub body: FunctionBody,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MixinIncludeDecl {\n    pub loc: SourcePointer,\n    pub what: Expression,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum StructEntry {\n    Method(Box<MethodDecl>),\n    Operator(Box<OperatorDecl>),\n    Variable(Box<ValDeclStatement>),\n    Struct(Box<StructDecl>),\n    Enum(Box<EnumDecl>),\n    MixinInclude(Box<MixinIncludeDecl>),\n}\n\nimpl StructEntry {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Self::Method(m) => &m.loc,\n            Self::Operator(o) => &o.loc,\n            Self::Variable(v) => &v.loc,\n            Self::Struct(s) => &s.loc,\n            Self::Enum(e) => &e.loc,\n            Self::MixinInclude(m) => &m.loc,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct StructDecl {\n    pub loc: SourcePointer,\n    pub name: Identifier,\n    pub inherits: Vec<Expression>,\n    pub body: Vec<StructEntry>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct MixinDecl {\n    pub loc: SourcePointer,\n    pub name: Identifier,\n    pub body: Vec<StructEntry>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct EnumCaseDecl {\n    pub loc: SourcePointer,\n    pub name: Identifier,\n    pub payload: Option<Expression>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\n#[allow(clippy::large_enum_variant)]\npub enum EnumDeclEntry {\n    EnumCaseDecl(EnumCaseDecl),\n    StructEntry(StructEntry),\n}\n\nimpl EnumDeclEntry {\n    pub fn loc(&self) -> &SourcePointer {\n        match self {\n            Self::EnumCaseDecl(e) => &e.loc,\n            Self::StructEntry(s) => s.loc(),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct EnumDecl {\n    pub loc: SourcePointer,\n    pub name: Identifier,\n    pub body: Vec<EnumDeclEntry>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ExtensionDecl {\n    pub loc: SourcePointer,\n    pub target: Expression,\n    pub inherits: Vec<Expression>,\n    pub body: Vec<StructEntry>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ImportPath {\n    pub loc: SourcePointer,\n    pub entries: Vec<Identifier>,\n}\n\nimpl ImportPath {\n    pub fn from_dotted_string(loc: SourcePointer, dotted: &str) -> Self {\n        Self {\n            loc: loc.clone(),\n            entries: dotted\n                .split('.')\n                .map(|x| Identifier {\n                    loc: loc.clone(),\n                    value: x.to_owned(),\n                })\n                .collect(),\n        }\n    }\n\n    pub fn to_dotted_string(&self) -> String {\n        self.entries\n            .iter()\n            .map(|x| x.value.clone())\n            .collect::<Vec<_>>()\n            .join(\".\")\n    }\n\n    pub fn to_path_string(&self) -> String {\n        self.entries\n            .iter()\n            .map(|x| x.value.clone())\n            .collect::<Vec<_>>()\n            .join(\"/\")\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ImportStatement {\n    pub loc: SourcePointer,\n    pub what: ImportPath,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum ImportTarget {\n    IdentifierList(IdentifierList),\n    All,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ImportFromStatement {\n    pub loc: SourcePointer,\n    pub what: ImportTarget,\n    pub from: ImportPath,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub enum ModuleFlag {\n    NoStandardLibrary,\n    UsesDylib(String),\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ModuleFlags {\n    pub flags: Vec<ModuleFlag>,\n}\n\nimpl ModuleFlags {\n    pub fn empty() -> Self {\n        Self { flags: vec![] }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\n#[allow(clippy::large_enum_variant)]\npub enum TopLevelEntry {\n    ExpressionStatement(ExpressionStatement),\n    ValDeclStatement(ValDeclStatement),\n    WriteOpEqStatement(WriteOpEqStatement),\n    AssignStatement(AssignStatement),\n    FunctionDecl(FunctionDecl),\n    StructDecl(StructDecl),\n    MixinDecl(MixinDecl),\n    EnumDecl(EnumDecl),\n    ExtensionDecl(ExtensionDecl),\n    AssertStatement(AssertStatement),\n    ImportStatement(ImportStatement),\n    ImportFromStatement(ImportFromStatement),\n    IfStatement(IfStatement),\n    MatchStatement(MatchStatement),\n    WhileStatement(WhileStatement),\n    ForStatement(ForStatement),\n    CodeBlock(CodeBlock),\n    TryBlock(TryBlock),\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ParsedModule {\n    pub loc: SourcePointer,\n    pub flags: ModuleFlags,\n    pub entries: Vec<TopLevelEntry>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ParserError {\n    pub loc: SourcePointer,\n    pub msg: String,\n}\n\nimpl std::fmt::Display for ParserError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.msg)\n    }\n}\n\npub type ParserResult<T> = Result<T, ParserError>;\n\npub fn source_to_ast(source: &SourceBuffer) -> ParserResult<ParsedModule> {\n    let input = &source.as_str();\n    let parse_tree = HaxbyParser::parse(Rule::module, input);\n    match parse_tree {\n        Ok(mut pt) => Ok(<ParsedModule as derive::Derive>::from_parse_tree(\n            pt.next_back().expect(\"invalid parse tree\"),\n            source,\n        )),\n        Err(err) => {\n            let loc = From::from(&err.location);\n            let ptr = source.pointer(loc);\n            Err(ParserError {\n                loc: ptr,\n                msg: err.variant.message().to_string(),\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/add_eq_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AddEqSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for AddEqSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::add_op_eq);\n        match p.as_str() {\n            \"+=\" => Self::PlusEq,\n            \"-=\" => Self::MinusEq,\n            \"*=\" => Self::StarEq,\n            \"/=\" => Self::SlashEq,\n            \"%=\" => Self::PercentEq,\n            \"<<=\" => Self::ShiftLeftEq,\n            \">>=\" => Self::ShiftRightEq,\n            _ => panic!(\"operator expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for AddEqSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::PlusEq => \"+=\",\n            Self::MinusEq => \"-=\",\n            Self::StarEq => \"*=\",\n            Self::SlashEq => \"/=\",\n            Self::PercentEq => \"%=\",\n            Self::ShiftLeftEq => \"<<=\",\n            Self::ShiftRightEq => \">>=\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/add_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AddOperation, AddSymbol, MulOperation, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for AddOperation {\n    #[allow(clippy::len_zero)]\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::add);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        if inner.len() == 1 {\n            let left = MulOperation::from_parse_tree(inner.peek().expect(\"need a mul\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: vec![],\n            }\n        } else if inner.len() > 0 {\n            let left =\n                MulOperation::from_parse_tree(inner.next().expect(\"need a left mul\"), source);\n            let mut right = vec![];\n            loop {\n                let op = inner.next();\n                if op.is_none() {\n                    break;\n                };\n                let op = AddSymbol::from_parse_tree(op.unwrap(), source);\n                let atom = MulOperation::from_parse_tree(\n                    inner.next().expect(\"add needs a right hand side\"),\n                    source,\n                );\n                right.push((op, atom));\n            }\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right,\n            }\n        } else {\n            panic!(\"add does not contain\")\n        }\n    }\n}\n\nimpl PrettyPrintable for AddOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let mut this = self.left.prettyprint(buffer);\n        for (op, atom) in &self.right {\n            this = this << op << atom;\n        }\n        this\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/add_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AddSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for AddSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::add_op);\n        match p.as_str() {\n            \"+\" => Self::Plus,\n            \"-\" => Self::Minus,\n            _ => panic!(\"+ or - expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for AddSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Plus => \"+\",\n            Self::Minus => \"-\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/argument_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ArgumentDecl, DeclarationId, Expression, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ArgumentDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::arg_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let id = DeclarationId::from_parse_tree(inner.next().expect(\"expected decl_id\"), source);\n        let deft = inner.next().map(|p| Expression::from_parse_tree(p, source));\n        Self {\n            loc: source.pointer(loc),\n            id,\n            deft,\n        }\n    }\n}\n\nimpl PrettyPrintable for ArgumentDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer << &self.id;\n        if let Some(deft) = &self.deft {\n            buffer << \" = \" << deft\n        } else {\n            buffer\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/argument_list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ArgumentDecl, ArgumentList, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ArgumentList {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::arg_list);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let mut names = vec![];\n        let mut vararg = false;\n        for e in inner {\n            if e.as_rule() == Rule::vararg_marker {\n                vararg = true;\n            } else if e.as_rule() == Rule::arg_decl {\n                names.push(ArgumentDecl::from_parse_tree(e, source));\n            } else {\n                panic!(\"Unexpected rule in argument list: {:?}\", e.as_rule());\n            }\n        }\n        Self {\n            loc: source.pointer(loc),\n            names,\n            vararg,\n        }\n    }\n}\n\nimpl PrettyPrintable for ArgumentList {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer.write_separated_list(&self.names, \",\");\n        if self.vararg { buffer << \"...\" } else { buffer }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/assert_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AssertStatement, Expression,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for AssertStatement {\n    gen_from_components!(assert_stmt; val: Expression);\n}\n\nimpl PrettyPrintable for AssertStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"assert \" << &self.val << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/assign_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::ast::{\n    AssignStatement, Expression, PostfixExpression,\n    derive::Derive,\n    prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n};\n\nimpl Derive for AssignStatement {\n    fn from_parse_tree(\n        p: pest::iterators::Pair<'_, crate::grammar::Rule>,\n        source: &crate::ast::SourceBuffer,\n    ) -> Self {\n        assert!(p.as_rule() == crate::grammar::Rule::val_write_stmt);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let mut id = vec![];\n        let mut val = vec![];\n        for next in inner {\n            match next.as_rule() {\n                crate::grammar::Rule::postfix_lv => {\n                    id.push(<PostfixExpression>::from_parse_tree(next, source));\n                }\n                crate::grammar::Rule::expression => {\n                    val.push(<Expression>::from_parse_tree(next, source));\n                }\n                _ => panic!(\"unexpected token, want postfix_lv or expression\"),\n            }\n        }\n        Self {\n            loc: source.pointer(loc),\n            id,\n            val,\n        }\n    }\n}\n\nimpl PrettyPrintable for AssignStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer\n            .write_separated_list(&self.id, \", \")\n            .write(\" = \")\n            .write_separated_list(&self.val, \", \")\n            << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/break_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        BreakStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for BreakStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::break_stmt);\n        let loc = From::from(&p.as_span());\n        Self {\n            loc: source.pointer(loc),\n        }\n    }\n}\n\nimpl PrettyPrintable for BreakStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"break;\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/code_block.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, SourceBuffer, Statement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for CodeBlock {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::code_block);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let entries = inner\n            .map(|e| Statement::from_parse_tree(e, source))\n            .collect::<Vec<_>>();\n        Self {\n            loc: source.pointer(loc),\n            entries,\n        }\n    }\n}\n\nimpl PrettyPrintable for CodeBlock {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_indented_list(&self.entries, \"{\\n\", \"\\n\", \"\\n}\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/comp_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CompOperation, CompSymbol, RelOperation, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for CompOperation {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::comp);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        if inner.len() == 1 {\n            let left = RelOperation::from_parse_tree(inner.peek().expect(\"need a add\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: None,\n            }\n        } else {\n            let left = RelOperation::from_parse_tree(inner.next().expect(\"need first add\"), source);\n            let op = CompSymbol::from_parse_tree(inner.next().expect(\"need op\"), source);\n            let right =\n                RelOperation::from_parse_tree(inner.next().expect(\"need second add\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: Some((op, right)),\n            }\n        }\n    }\n}\n\nimpl PrettyPrintable for CompOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let this = self.left.prettyprint(buffer);\n        if let Some(right) = &self.right {\n            this << \" \" << &right.0 << \" \" << &right.1\n        } else {\n            this\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/comp_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CompSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for CompSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::comp_op);\n        match p.as_str() {\n            \"==\" => Self::Equal,\n            \"!=\" => Self::NotEqual,\n            \"isa\" => Self::Isa,\n            _ => panic!(\"* or / expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for CompSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Equal => \"==\",\n            Self::NotEqual => \"!=\",\n            Self::Isa => \"isa\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/continue_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ContinueStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ContinueStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::continue_stmt);\n        let loc = From::from(&p.as_span());\n        Self {\n            loc: source.pointer(loc),\n        }\n    }\n}\n\nimpl PrettyPrintable for ContinueStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"continue;\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/declaration_id.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        DeclarationId, Expression, Identifier, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for DeclarationId {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::decl_id);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let ty = inner\n            .next()\n            .map(|next| Expression::from_parse_tree(next, source));\n        Self {\n            loc: source.pointer(loc),\n            name,\n            ty,\n        }\n    }\n}\n\nimpl PrettyPrintable for DeclarationId {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer << &self.name;\n        if let Some(ty) = &self.ty {\n            buffer << \" : \" << ty\n        } else {\n            buffer\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/else_piece.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, ElsePiece, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ElsePiece {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::else_piece);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let body = inner.next().expect(\"need body\");\n        let then = CodeBlock::from_parse_tree(body, source);\n        Self {\n            loc: source.pointer(loc),\n            then,\n        }\n    }\n}\n\nimpl PrettyPrintable for ElsePiece {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"else \" << &self.then\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/elsif_piece.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ElsifPiece, IfCondPiece, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ElsifPiece {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::elsif_piece);\n        let mut inner = p.into_inner();\n        let content = inner.next().expect(\"need content\");\n        let content = IfCondPiece::from_parse_tree(content, source);\n        Self { content }\n    }\n}\n\nimpl PrettyPrintable for ElsifPiece {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"elsif \" << &self.content\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/enum_case_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        EnumCaseDecl, Expression, Identifier, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for EnumCaseDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::enum_case_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let payload = inner\n            .next()\n            .map(|next| Expression::from_parse_tree(next, source));\n        Self {\n            loc: source.pointer(loc),\n            name,\n            payload,\n        }\n    }\n}\n\nimpl PrettyPrintable for EnumCaseDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer << &self.name;\n        if let Some(payload) = &self.payload {\n            buffer << \"(\" << payload << \")\"\n        } else {\n            buffer\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/enum_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        EnumCaseDecl, EnumDecl, EnumDeclEntry, Identifier, SourceBuffer, StructEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for EnumDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::enum_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let mut entries = vec![];\n        for next in inner {\n            if next.as_rule() != Rule::enum_decl_entry {\n                panic!(\"invalid enum entry :{next}\");\n            }\n            let inner_rule = next.into_inner().next().expect(\"need enum entry\");\n            match inner_rule.as_rule() {\n                Rule::struct_entry => {\n                    entries.push(EnumDeclEntry::StructEntry(StructEntry::from_parse_tree(\n                        inner_rule, source,\n                    )));\n                }\n                Rule::enum_case_decl => {\n                    entries.push(EnumDeclEntry::EnumCaseDecl(EnumCaseDecl::from_parse_tree(\n                        inner_rule, source,\n                    )));\n                }\n                _ => panic!(\"invalid enum entry :{inner_rule}\"),\n            }\n        }\n        Self {\n            loc: source.pointer(loc),\n            name,\n            body: entries,\n        }\n    }\n}\n\nimpl PrettyPrintable for EnumDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        (buffer << \"enum \" << &self.name).write_indented_list(&self.body, \"{\\n\", \"\\n\", \"\\n}\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/enum_decl_entry.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        EnumDeclEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nuse crate::ast::{EnumCaseDecl, StructEntry};\n\nimpl Derive for EnumDeclEntry {\n    gen_from_options!(enum_decl_entry; (enum_case_decl, EnumCaseDecl), (struct_entry, StructEntry));\n}\n\nimpl PrettyPrintable for EnumDeclEntry {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::EnumCaseDecl(e) => e.prettyprint(buffer),\n            Self::StructEntry(s) => s.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::TernaryExpression,\n    ast::{\n        Expression, LambdaFunction, LogOperation, SourceBuffer, TryUnwrapExpression,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for Expression {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::expression);\n        let content = p.into_inner().next().expect(\"needs an atom inside\");\n        match content.as_rule() {\n            Rule::log => Self::LogOperation(LogOperation::from_parse_tree(content, source)),\n            Rule::lambda_f => {\n                Self::LambdaFunction(LambdaFunction::from_parse_tree(content, source))\n            }\n            Rule::ternary_expr => {\n                Self::TernaryExpression(TernaryExpression::from_parse_tree(content, source))\n            }\n            Rule::try_unwrap_expr => {\n                Self::TryUnwrapExpression(TryUnwrapExpression::from_parse_tree(content, source))\n            }\n            _ => panic!(\"atom does not contain\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for Expression {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Expression::LogOperation(c) => c.prettyprint(buffer),\n            Expression::LambdaFunction(f) => f.prettyprint(buffer),\n            Expression::TernaryExpression(t) => t.prettyprint(buffer),\n            Expression::TryUnwrapExpression(t) => t.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/expression_list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, ExpressionList, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ExpressionList {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::expr_list);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let expressions = inner\n            .map(|e| Expression::from_parse_tree(e, source))\n            .collect::<Vec<_>>();\n        Self {\n            loc: source.pointer(loc),\n            expressions,\n        }\n    }\n}\n\nimpl PrettyPrintable for ExpressionList {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_separated_list(&self.expressions, \",\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/expression_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, ExpressionStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ExpressionStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::expr_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let val = inner.next().map(|p| Expression::from_parse_tree(p, source));\n        Self {\n            loc: source.pointer(loc),\n            val,\n        }\n    }\n}\n\nimpl PrettyPrintable for ExpressionStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        if let Some(val) = &self.val {\n            buffer << val << \";\"\n        } else {\n            buffer << \";\"\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/extension_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, ExtensionDecl, SourceBuffer, StructEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ExtensionDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::extension_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let target = Expression::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let inherits = if let Some(next) = inner.peek() {\n            if next.as_rule() == Rule::expr_list {\n                let expr_list = inner.next().unwrap();\n                expr_list\n                    .into_inner()\n                    .map(|expr| Expression::from_parse_tree(expr, source))\n                    .collect()\n            } else {\n                vec![]\n            }\n        } else {\n            vec![]\n        };\n        let mut body = vec![];\n        for next in inner {\n            let next = StructEntry::from_parse_tree(next, source);\n            body.push(next);\n        }\n        Self {\n            loc: source.pointer(loc),\n            target,\n            inherits,\n            body,\n        }\n    }\n}\n\nimpl PrettyPrintable for ExtensionDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        (buffer << \"extension \" << &self.target).write_indented_list(&self.body, \"{\\n\", \"\\n\", \"\\n}\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/float_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        FloatLiteral, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for FloatLiteral {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::fp_literal);\n        let loc = From::from(&p.as_span());\n        Self {\n            loc: source.pointer(loc),\n            val: p.as_str().to_owned(),\n        }\n    }\n}\n\nimpl PrettyPrintable for FloatLiteral {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(&self.val)\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/for_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, ElsePiece, Expression, ForStatement, Identifier,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ForStatement {\n    fn from_parse_tree(\n        p: pest::iterators::Pair<'_, crate::grammar::Rule>,\n        source: &crate::ast::SourceBuffer,\n    ) -> Self {\n        assert!(p.as_rule() == Rule::for_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let id = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let expr = Expression::from_parse_tree(inner.next().expect(\"need expression\"), source);\n        let then = CodeBlock::from_parse_tree(inner.next().expect(\"need then block\"), source);\n        let els = inner\n            .next()\n            .map(|else_p| ElsePiece::from_parse_tree(else_p, source));\n\n        Self {\n            loc: source.pointer(loc),\n            id,\n            expr,\n            then,\n            els,\n        }\n    }\n}\n\nimpl PrettyPrintable for ForStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"for( \" << &self.id << \" in \" << &self.expr << \") \" << &self.then\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/function_body.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, Expression, FunctionBody, ReturnStatement, SourceBuffer, Statement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for FunctionBody {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::function_body);\n        let loc = From::from(&p.as_span());\n        let mut inner_body = p.into_inner();\n        let i = inner_body.next().expect(\"need inner body part\");\n        match i.as_rule() {\n            Rule::code_block => Self {\n                code: CodeBlock::from_parse_tree(i, source),\n            },\n            Rule::expression => {\n                let expr = Expression::from_parse_tree(i, source);\n                let return_stmt = ReturnStatement {\n                    loc: expr.loc().clone(),\n                    val: Some(expr),\n                };\n                Self {\n                    code: CodeBlock {\n                        loc: source.pointer(loc),\n                        entries: vec![Statement::ReturnStatement(return_stmt)],\n                    },\n                }\n            }\n            _ => panic!(\"Unexpected rule for inner function body: {i:?}\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for FunctionBody {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.code\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/function_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ArgumentList, FunctionBody, FunctionDecl, Identifier, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for FunctionDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::function_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let p = inner.peek().unwrap();\n        let args = if p.as_rule() == Rule::arg_list {\n            let p = inner.next().unwrap();\n            ArgumentList::from_parse_tree(p, source)\n        } else {\n            ArgumentList::empty(source.pointer(loc))\n        };\n        let body = FunctionBody::from_parse_tree(inner.next().expect(\"need body\"), source);\n        Self {\n            loc: source.pointer(loc),\n            name,\n            args,\n            body,\n        }\n    }\n}\n\nimpl PrettyPrintable for FunctionDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"func \" << &self.name << \" (\" << &self.args << \") \" << &self.body\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/identifier.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Identifier, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for Identifier {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::identifier);\n        let loc = From::from(&p.as_span());\n        Self {\n            loc: source.pointer(loc),\n            value: p.as_str().to_owned(),\n        }\n    }\n}\n\nimpl PrettyPrintable for Identifier {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(&self.value)\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/identifier_list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Identifier, IdentifierList, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for IdentifierList {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::ident_list);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let identifiers = inner\n            .map(|e| Identifier::from_parse_tree(e, source))\n            .collect::<Vec<_>>();\n        Self {\n            loc: source.pointer(loc),\n            identifiers,\n        }\n    }\n}\n\nimpl PrettyPrintable for IdentifierList {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_separated_list(&self.identifiers, \",\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/if_cond_piece.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, Expression, IfCondPiece, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for IfCondPiece {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::if_cond_piece);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let expr = inner.next().expect(\"need expression\");\n        let body = inner.next().expect(\"need body\");\n        let expression = Expression::from_parse_tree(expr, source);\n        let then = CodeBlock::from_parse_tree(body, source);\n        Self {\n            loc: source.pointer(loc),\n            expression: Box::new(expression),\n            then,\n        }\n    }\n}\n\nimpl PrettyPrintable for IfCondPiece {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"(\" << &self.expression << \")\" << &self.then\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/if_piece.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        IfCondPiece, IfPiece, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for IfPiece {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::if_piece);\n        let mut inner = p.into_inner();\n        let content = inner.next().expect(\"need content\");\n        let content = IfCondPiece::from_parse_tree(content, source);\n        Self { content }\n    }\n}\n\nimpl PrettyPrintable for IfPiece {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"if \" << &self.content\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/if_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ElsePiece, ElsifPiece, IfPiece, IfStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for IfStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::if_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let ifpiece = inner.next().expect(\"need if piece\");\n        let iff = IfPiece::from_parse_tree(ifpiece, source);\n        let mut elsif_pieces = vec![];\n        loop {\n            let p = inner.peek();\n            if p.is_none() {\n                break;\n            }\n            if p.unwrap().as_rule() != Rule::elsif_piece {\n                break;\n            }\n            let p = inner.next().unwrap();\n            let elsif_rule = ElsifPiece::from_parse_tree(p, source);\n            elsif_pieces.push(elsif_rule);\n        }\n        let p = inner.peek();\n        let els = if p.is_none() {\n            None\n        } else {\n            let els_piece = inner.next().unwrap();\n            let els = ElsePiece::from_parse_tree(els_piece, source);\n            Some(els)\n        };\n        Self {\n            loc: source.pointer(loc),\n            iff,\n            elsif: elsif_pieces,\n            els,\n        }\n    }\n}\n\nimpl PrettyPrintable for IfStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let mut this = self.iff.prettyprint(buffer);\n        for elsif in &self.elsif {\n            this = elsif.prettyprint(this);\n        }\n        this << &self.els\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/import_from_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ImportFromStatement, ImportPath, ImportTarget, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ImportFromStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::import_id_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let what = ImportTarget::from_parse_tree(inner.next().expect(\"need identifiers\"), source);\n        let from = ImportPath::from_parse_tree(inner.next().expect(\"need a path\"), source);\n        Self {\n            loc: source.pointer(loc),\n            what,\n            from,\n        }\n    }\n}\n\nimpl PrettyPrintable for ImportFromStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"import \" << &self.what << \" from \" << &self.from << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/import_path.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Identifier, ImportPath, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ImportPath {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::import_path);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let entries = inner\n            .map(|x| Identifier::from_parse_tree(x, source))\n            .collect();\n        Self {\n            loc: source.pointer(loc),\n            entries,\n        }\n    }\n}\n\nimpl PrettyPrintable for ImportPath {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_separated_list(&self.entries, \".\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/import_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ImportPath, ImportStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ImportStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::import_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let what = ImportPath::from_parse_tree(inner.next().expect(\"need a path\"), source);\n        Self {\n            loc: source.pointer(loc),\n            what,\n        }\n    }\n}\n\nimpl PrettyPrintable for ImportStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"import \" << &self.what << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/import_target.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        IdentifierList, ImportTarget, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ImportTarget {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::import_target);\n        let mut inner = p.into_inner();\n        let tgt = inner.next().expect(\"need an import target\");\n        match tgt.as_rule() {\n            Rule::ident_list => Self::IdentifierList(IdentifierList::from_parse_tree(tgt, source)),\n            Rule::import_all => Self::All,\n            _ => panic!(\"invalid import target\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for ImportTarget {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            ImportTarget::IdentifierList(il) => il.prettyprint(buffer),\n            ImportTarget::All => buffer << \"*\",\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/int_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::ast::{\n    IntLiteral, IntLiteralBase,\n    derive::Derive,\n    prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n};\n\nimpl Derive for IntLiteral {\n    fn from_parse_tree(\n        p: pest::iterators::Pair<'_, crate::grammar::Rule>,\n        source: &crate::ast::SourceBuffer,\n    ) -> Self {\n        assert!(p.as_rule() == crate::grammar::Rule::int_literal);\n        let loc = From::from(&p.as_span());\n        let val = p.as_str().to_owned();\n        let base = match p\n            .into_inner()\n            .next()\n            .expect(\"need a literal content\")\n            .as_rule()\n        {\n            crate::grammar::Rule::bin_int_literal => IntLiteralBase::Binary,\n            crate::grammar::Rule::oct_int_literal => IntLiteralBase::Octal,\n            crate::grammar::Rule::dec_int_literal => IntLiteralBase::Decimal,\n            crate::grammar::Rule::hex_int_literal => IntLiteralBase::Hexadecimal,\n            _ => panic!(\"unexpected int literal base\"),\n        };\n        Self {\n            loc: source.pointer(loc),\n            base,\n            val,\n        }\n    }\n}\n\nimpl PrettyPrintable for IntLiteral {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(&self.val)\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/lambda_body.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, Expression, LambdaBody,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nimpl Derive for LambdaBody {\n    gen_from_options!(lambda_f_body; (code_block, CodeBlock), (expression, Expression));\n}\n\nimpl PrettyPrintable for LambdaBody {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            LambdaBody::CodeBlock(c) => c.prettyprint(buffer),\n            LambdaBody::Expression(e) => e.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/lambda_function.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ArgumentList, LambdaBody, LambdaFunction, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for LambdaFunction {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::lambda_f);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let args = ArgumentList::from_parse_tree(inner.next().expect(\"need arguments\"), source);\n        let body = LambdaBody::from_parse_tree(inner.next().expect(\"need body\"), source);\n        Self {\n            loc: source.pointer(loc),\n            args,\n            body: Box::new(body),\n        }\n    }\n}\n\nimpl PrettyPrintable for LambdaFunction {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"|\" << &self.args << \"| => \" << &self.body\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/list_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ExpressionList, ListLiteral, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ListLiteral {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::list_literal);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let items = if let Some(next) = inner.next() {\n            ExpressionList::from_parse_tree(next, source)\n        } else {\n            ExpressionList::empty(source.pointer(loc))\n        };\n        Self {\n            loc: source.pointer(loc),\n            items,\n        }\n    }\n}\n\nimpl PrettyPrintable for ListLiteral {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"[\" << &self.items << \"]\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/log_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CompOperation, LogOperation, LogSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for LogOperation {\n    #[allow(clippy::len_zero)]\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::log);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        if inner.len() == 1 {\n            let left = CompOperation::from_parse_tree(inner.peek().expect(\"need a mul\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: vec![],\n            }\n        } else if inner.len() > 0 {\n            let left =\n                CompOperation::from_parse_tree(inner.next().expect(\"need a left mul\"), source);\n            let mut right = vec![];\n            loop {\n                let op = inner.next();\n                if op.is_none() {\n                    break;\n                };\n                let op = LogSymbol::from_parse_tree(op.unwrap(), source);\n                let atom = CompOperation::from_parse_tree(\n                    inner.next().expect(\"add needs a right hand side\"),\n                    source,\n                );\n                right.push((op, atom));\n            }\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right,\n            }\n        } else {\n            panic!(\"add does not contain\")\n        }\n    }\n}\n\nimpl PrettyPrintable for LogOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let mut this = self.left.prettyprint(buffer);\n        for (op, atom) in &self.right {\n            this = this << op << atom;\n        }\n        this\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/log_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        LogSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for LogSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::log_op);\n        match p.as_str() {\n            \"&\" => Self::Ampersand,\n            \"^\" => Self::Caret,\n            \"|\" => Self::Pipe,\n            \"&&\" => Self::DoubleAmpersand,\n            \"||\" => Self::DoublePipe,\n            _ => panic!(\"&^| expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for LogSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Ampersand => \"&\",\n            Self::DoubleAmpersand => \"&&\",\n            Self::Caret => \"^\",\n            Self::Pipe => \"|\",\n            Self::DoublePipe => \"||\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/match_pattern.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        MatchPattern, MatchPatternComp, MatchPatternEnumCase, MatchPatternRel,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nimpl Derive for MatchPattern {\n    gen_from_options!(\n        match_pattern;\n        (match_pattern_comp, MatchPatternComp),\n        (match_pattern_enum_case, MatchPatternEnumCase),\n        (match_pattern_rel, MatchPatternRel),\n    );\n}\n\nimpl PrettyPrintable for MatchPattern {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::MatchPatternComp(e) => e.prettyprint(buffer),\n            Self::MatchPatternRel(e) => e.prettyprint(buffer),\n            Self::MatchPatternEnumCase(e) => e.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/match_pattern_comp.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CompSymbol, Expression, MatchPatternComp,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for MatchPatternComp {\n    gen_from_components!(match_pattern_comp; op: CompSymbol, expr: Expression);\n}\n\nimpl PrettyPrintable for MatchPatternComp {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.op << &self.expr\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/match_pattern_enum_case.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        DeclarationId, Identifier, MatchPatternEnumCase, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MatchPatternEnumCase {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::match_pattern_enum_case);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let case = Identifier::from_parse_tree(inner.next().expect(\"need expression\"), source);\n        let payload = inner\n            .next()\n            .map(|next| DeclarationId::from_parse_tree(next, source));\n        Self {\n            loc: source.pointer(loc),\n            case,\n            payload,\n        }\n    }\n}\n\nimpl PrettyPrintable for MatchPatternEnumCase {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer << \" case \" << &self.case;\n        if let Some(p) = &self.payload {\n            buffer << \"(\" << p << \")\"\n        } else {\n            buffer\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/match_pattern_rel.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, MatchPatternRel, RelSymbol,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for MatchPatternRel {\n    gen_from_components!(match_pattern_rel; op: RelSymbol, expr: Expression);\n}\n\nimpl PrettyPrintable for MatchPatternRel {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.op << &self.expr\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/match_rule.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, MatchPattern, MatchRule, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MatchRule {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::match_rule);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let mut patterns = vec![];\n        let then = {\n            loop {\n                let next = inner.next().expect(\"need rules\");\n                match next.as_rule() {\n                    Rule::match_pattern => {\n                        patterns.push(MatchPattern::from_parse_tree(next, source));\n                    }\n                    Rule::code_block => {\n                        break CodeBlock::from_parse_tree(next, source);\n                    }\n                    _ => panic!(\"invalid rule entry\"),\n                }\n            }\n        };\n        Self {\n            loc: source.pointer(loc),\n            patterns,\n            then,\n        }\n    }\n}\n\nimpl PrettyPrintable for MatchRule {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_separated_list(&self.patterns, \" and \") << \" => \" << &self.then\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/match_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ElsePiece, Expression, MatchRule, MatchStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MatchStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::match_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let expr = Expression::from_parse_tree(inner.next().expect(\"need expression\"), source);\n        let mut rules = vec![];\n        let els = {\n            loop {\n                let next = match inner.next() {\n                    Some(x) => x,\n                    None => {\n                        break None;\n                    }\n                };\n                match next.as_rule() {\n                    Rule::match_rule => {\n                        rules.push(MatchRule::from_parse_tree(next, source));\n                    }\n                    Rule::else_piece => {\n                        break Some(ElsePiece::from_parse_tree(next, source));\n                    }\n                    _ => panic!(\"invalid rule entry\"),\n                }\n            }\n        };\n        Self {\n            loc: source.pointer(loc),\n            expr,\n            rules,\n            els,\n        }\n    }\n}\n\nimpl PrettyPrintable for MatchStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer =\n            (buffer << \"match \" << &self.expr).write_indented_list(&self.rules, \"{\\n\", \"\\n\", \"\");\n        if let Some(e) = &self.els {\n            buffer << \"\\n else \" << e << \"\\n}\"\n        } else {\n            buffer << \"\\n}\"\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/method_access.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        MethodAccess, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MethodAccess {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::method_access);\n        match p.as_str() {\n            \"instance\" => Self::Instance,\n            \"type\" => Self::Type,\n            _ => panic!(\"instance or type expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for MethodAccess {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer\n            << match self {\n                MethodAccess::Instance => \"instance\",\n                MethodAccess::Type => \"type\",\n            }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/method_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ArgumentList, FunctionBody, Identifier, MethodAccess, MethodDecl, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MethodDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::method_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let next = inner.peek().expect(\"expected next\");\n        let access = if next.as_rule() == Rule::method_access {\n            MethodAccess::from_parse_tree(inner.next().unwrap(), source)\n        } else {\n            MethodAccess::Instance\n        };\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let p = inner.peek().unwrap();\n        let args = if p.as_rule() == Rule::arg_list {\n            let p = inner.next().unwrap();\n            ArgumentList::from_parse_tree(p, source)\n        } else {\n            ArgumentList::empty(source.pointer(loc))\n        };\n        let body = FunctionBody::from_parse_tree(inner.next().expect(\"need body\"), source);\n        Self {\n            loc: source.pointer(loc),\n            access,\n            name,\n            args,\n            body,\n        }\n    }\n}\n\nimpl PrettyPrintable for MethodDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.access << \" func \" << &self.name << \" (\" << &self.args << \") \" << &self.body\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/mixin_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Identifier, MixinDecl, SourceBuffer, StructEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MixinDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::mixin_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let mut body = vec![];\n        for next in inner {\n            let next = StructEntry::from_parse_tree(next, source);\n            body.push(next);\n        }\n        Self {\n            loc: source.pointer(loc),\n            name,\n            body,\n        }\n    }\n}\n\nimpl PrettyPrintable for MixinDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        (buffer << \"mixin \" << &self.name).write_indented_list(&self.body, \"{\\n\", \"\\n\", \"\\n}\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/mixin_include_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, MixinIncludeDecl,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for MixinIncludeDecl {\n    gen_from_components!(mixin_include_decl; what: Expression);\n}\n\nimpl PrettyPrintable for MixinIncludeDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"include \" << &self.what\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nmod add_eq_symbol;\nmod add_operation;\nmod add_symbol;\nmod argument_decl;\nmod argument_list;\nmod assert_statement;\nmod assign_statement;\nmod break_statement;\nmod code_block;\nmod comp_operation;\nmod comp_symbol;\nmod continue_statement;\nmod declaration_id;\nmod else_piece;\nmod elsif_piece;\nmod enum_case_decl;\nmod enum_decl;\nmod enum_decl_entry;\nmod expression;\nmod expression_list;\nmod expression_statement;\nmod extension_decl;\nmod float_literal;\nmod for_statement;\nmod function_body;\nmod function_decl;\nmod identifier;\nmod identifier_list;\nmod if_cond_piece;\nmod if_piece;\nmod if_statement;\nmod import_from_statement;\nmod import_path;\nmod import_statement;\nmod import_target;\nmod int_literal;\nmod lambda_body;\nmod lambda_function;\nmod list_literal;\nmod log_operation;\nmod log_symbol;\nmod match_pattern;\nmod match_pattern_comp;\nmod match_pattern_enum_case;\nmod match_pattern_rel;\nmod match_rule;\nmod match_statement;\nmod method_access;\nmod method_decl;\nmod mixin_decl;\nmod mixin_include_decl;\nmod module_flag;\nmod module_flags;\nmod mul_operation;\nmod mul_symbol;\nmod operator_decl;\nmod operator_symbol;\nmod paren_expression;\nmod parsed_module;\nmod postfix_expression;\nmod postfix_rvalue;\nmod postfix_term;\nmod postfix_term_attribute;\nmod postfix_term_call;\nmod postfix_term_enum_case;\nmod postfix_term_field_write;\nmod postfix_term_index;\nmod postfix_term_index_write;\nmod postfix_term_object_write;\nmod postfix_term_try_protocol;\nmod postfix_term_write;\nmod postfix_term_write_list;\nmod primary;\nmod rel_operation;\nmod rel_symbol;\nmod return_statement;\nmod shift_operation;\nmod shift_symbol;\nmod statement;\nmod string_literal;\nmod struct_decl;\nmod struct_entry;\nmod ternary_expression;\nmod throw_statement;\nmod top_level_entry;\nmod try_block;\nmod try_unwrap_expression;\nmod unary_operation;\nmod unary_symbol;\nmod val_decl_entry;\nmod val_decl_statement;\nmod while_statement;\nmod write_op_eq_statement;\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/module_flag.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Identifier, ModuleFlag, SourceBuffer, StringLiteral,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ModuleFlag {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::module_flag);\n        let mut inner = p.into_inner();\n        let flag = Identifier::from_parse_tree(inner.next().expect(\"need flag\"), source);\n        match flag.value.as_str() {\n            \"no_std\" => Self::NoStandardLibrary,\n            \"uses_dylib\" => {\n                let path = StringLiteral::from_parse_tree(inner.next().expect(\"need path\"), source);\n                Self::UsesDylib(path.value)\n            }\n            _ => panic!(\"unknown module flag\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for ModuleFlag {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            ModuleFlag::NoStandardLibrary => buffer << \"flag: no_std;\",\n            ModuleFlag::UsesDylib(dylib) => buffer << \"flag: uses_dylib(\" << dylib.as_str() << \");\",\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/module_flags.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ModuleFlag, ModuleFlags, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ModuleFlags {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::module_flags);\n        let inner = p.into_inner();\n        let mut flags = vec![];\n        for entry in inner {\n            match entry.as_rule() {\n                Rule::module_flag => {\n                    flags.push(ModuleFlag::from_parse_tree(entry, source));\n                }\n                _ => panic!(\"invalid module flag\"),\n            }\n        }\n        Self { flags }\n    }\n}\n\nimpl PrettyPrintable for ModuleFlags {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_separated_list(&self.flags, \"\\n\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/mul_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        MulOperation, MulSymbol, SourceBuffer, UnaryOperation,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MulOperation {\n    #[allow(clippy::len_zero)]\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::mul);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let left = UnaryOperation::from_parse_tree(inner.peek().expect(\"need an atom\"), source);\n        if inner.len() == 1 {\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: vec![],\n            }\n        } else if inner.len() > 0 {\n            let _ = inner.next();\n            let mut right = vec![];\n            loop {\n                let op = inner.next();\n                if op.is_none() {\n                    break;\n                };\n                let op = MulSymbol::from_parse_tree(op.unwrap(), source);\n                let atom = UnaryOperation::from_parse_tree(\n                    inner.next().expect(\"mul needs a right hand side\"),\n                    source,\n                );\n                right.push((op, atom));\n            }\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right,\n            }\n        } else {\n            panic!(\"mul does not contain\")\n        }\n    }\n}\n\nimpl PrettyPrintable for MulOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let mut this = self.left.prettyprint(buffer);\n        for (op, atom) in &self.right {\n            this = this << op << atom;\n        }\n        this\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/mul_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        MulSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for MulSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::mul_op);\n        match p.as_str() {\n            \"*\" => MulSymbol::Star,\n            \"/\" => MulSymbol::Slash,\n            \"%\" => MulSymbol::Percent,\n            _ => panic!(\"one of *, / or % expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for MulSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Star => \"*\",\n            Self::Slash => \"/\",\n            Self::Percent => \"%\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/operator_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ArgumentList, FunctionBody, OperatorDecl, OperatorSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for OperatorDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::operator_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let next = inner.peek().expect(\"expected next\");\n        let reverse = if next.as_rule() == Rule::operator_direction {\n            let _ = inner.next();\n            true\n        } else {\n            false\n        };\n        let symbol =\n            OperatorSymbol::from_parse_tree(inner.next().expect(\"need operator symbol\"), source);\n        let next = inner.peek().unwrap();\n        let args = if next.as_rule() == Rule::arg_list {\n            let p = inner.next().unwrap();\n            ArgumentList::from_parse_tree(p, source)\n        } else {\n            ArgumentList::empty(source.pointer(loc))\n        };\n        let body = FunctionBody::from_parse_tree(inner.next().expect(\"need body\"), source);\n        Self {\n            loc: source.pointer(loc),\n            reverse,\n            symbol,\n            args,\n            body,\n        }\n    }\n}\n\nimpl PrettyPrintable for OperatorDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer\n            << if self.reverse {\n                \"reverse operator \"\n            } else {\n                \"operator \"\n            }\n            << &self.symbol\n            << \" (\"\n            << &self.args\n            << \") \"\n            << &self.body\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/operator_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        OperatorSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for OperatorSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::operator_symbol);\n        match p.as_str() {\n            \"+\" => Self::Plus,\n            \"-\" => Self::Minus,\n            \"u-\" => Self::UnaryMinus,\n            \"*\" => Self::Star,\n            \"/\" => Self::Slash,\n            \"%\" => Self::Percent,\n            \"<<\" => Self::LeftShift,\n            \">>\" => Self::RightShift,\n            \"==\" => Self::Equals,\n            \"<=\" => Self::LessThanEqual,\n            \">=\" => Self::GreaterThanEqual,\n            \"<\" => Self::LessThan,\n            \">\" => Self::GreaterThan,\n            \"&\" => Self::BitwiseAnd,\n            \"|\" => Self::BitwiseOr,\n            \"^\" => Self::BitwiseXor,\n            \"()\" => Self::Call,\n            \"[]\" => Self::GetSquareBrackets,\n            \"[]=\" => Self::SetSquareBrackets,\n            _ => panic!(\"valid operator symbol expected, found: {}\", p.as_str()),\n        }\n    }\n}\n\nimpl PrettyPrintable for OperatorSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Plus => \"+\",\n            Self::Minus => \"-\",\n            Self::UnaryMinus => \"u-\",\n            Self::Star => \"*\",\n            Self::Slash => \"/\",\n            Self::Percent => \"%\",\n            Self::LeftShift => \"<<\",\n            Self::RightShift => \">>\",\n            Self::LessThanEqual => \"<=\",\n            Self::GreaterThanEqual => \">=\",\n            Self::LessThan => \"<\",\n            Self::GreaterThan => \">\",\n            Self::Equals => \"==\",\n            Self::BitwiseAnd => \"&\",\n            Self::BitwiseOr => \"|\",\n            Self::BitwiseXor => \"^\",\n            Self::Call => \"()\",\n            Self::GetSquareBrackets => \"[]\",\n            Self::SetSquareBrackets => \"[]=\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/paren_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, ParenExpression, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ParenExpression {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::paren_expr);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let value = Expression::from_parse_tree(inner.next().expect(\"need expression\"), source);\n        Self {\n            loc: source.pointer(loc),\n            value: Box::new(value),\n        }\n    }\n}\n\nimpl PrettyPrintable for ParenExpression {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"(\" << &self.value << \")\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/parsed_module.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ModuleFlags, ParsedModule, SourceBuffer, TopLevelEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ParsedModule {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::module);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let mut flags = ModuleFlags::empty();\n        let mut entries = vec![];\n        for entry in inner {\n            match entry.as_rule() {\n                Rule::module_flags => flags = ModuleFlags::from_parse_tree(entry, source),\n                Rule::top_level_entry => {\n                    entries.push(TopLevelEntry::from_parse_tree(entry, source))\n                }\n                _ => {}\n            }\n        }\n        Self {\n            loc: source.pointer(loc),\n            flags,\n            entries,\n        }\n    }\n}\n\nimpl PrettyPrintable for ParsedModule {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        self.flags\n            .prettyprint(buffer)\n            .write_separated_list(&self.entries, \"\\n\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixExpression, PostfixTerm, Primary, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for PostfixExpression {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::postfix_lv);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let base = Primary::from_parse_tree(inner.next().expect(\"postfix need base\"), source);\n        let mut terms = vec![];\n        loop {\n            let next = inner.next();\n            if next.is_none() {\n                break;\n            };\n            let next = PostfixTerm::from_parse_tree(next.expect(\"need postfix term\"), source);\n            terms.push(next);\n        }\n        Self {\n            loc: source.pointer(loc),\n            base,\n            terms,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixExpression {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let mut this = self.base.prettyprint(buffer);\n        for term in &self.terms {\n            this = term.prettyprint(this);\n        }\n        this\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_rvalue.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixExpression, PostfixRvalue,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for PostfixRvalue {\n    gen_from_components!(postfix_rv; expr: PostfixExpression);\n}\n\nimpl PrettyPrintable for PostfixRvalue {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        self.expr.prettyprint(buffer)\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixTerm,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nuse crate::ast::{\n    PostfixTermAttribute, PostfixTermCall, PostfixTermEnumCase, PostfixTermIndex,\n    PostfixTermObjectWrite, PostfixTermTryProtocol,\n};\n\nimpl Derive for PostfixTerm {\n    gen_from_options!(\n        postfix_term;\n        (postfix_term_attrib, PostfixTermAttribute),\n        (postfix_term_index, PostfixTermIndex),\n        (postfix_term_call, PostfixTermCall),\n        (postfix_term_enum_case, PostfixTermEnumCase),\n        (postfix_term_object_write, PostfixTermObjectWrite),\n        (postfix_term_try_protocol, PostfixTermTryProtocol)\n    );\n}\n\nimpl PrettyPrintable for PostfixTerm {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::PostfixTermAttribute(a) => a.prettyprint(buffer),\n            Self::PostfixTermIndex(i) => i.prettyprint(buffer),\n            Self::PostfixTermCall(c) => c.prettyprint(buffer),\n            Self::PostfixTermEnumCase(c) => c.prettyprint(buffer),\n            Self::PostfixTermObjectWrite(w) => w.prettyprint(buffer),\n            Self::PostfixTermTryProtocol(t) => t.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_attribute.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Identifier, PostfixTermAttribute,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for PostfixTermAttribute {\n    gen_from_components!(postfix_term_attrib; id: Identifier);\n}\n\nimpl PrettyPrintable for PostfixTermAttribute {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \".\" << &self.id\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_call.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ExpressionList, PostfixTermCall, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for PostfixTermCall {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::postfix_term_call);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let args = inner.find(|val| val.as_rule() == Rule::expr_list);\n        let args = if let Some(el) = args {\n            ExpressionList::from_parse_tree(el, source)\n        } else {\n            ExpressionList::empty(source.pointer(loc))\n        };\n        Self {\n            loc: source.pointer(loc),\n            args,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermCall {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"(\" << &self.args << \")\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_enum_case.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, Identifier, PostfixTermEnumCase, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for PostfixTermEnumCase {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::postfix_term_enum_case);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let id = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let payload = inner\n            .next()\n            .map(|next| Expression::from_parse_tree(next, source));\n        Self {\n            loc: source.pointer(loc),\n            id,\n            payload,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermEnumCase {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer << \"::\" << &self.id;\n        if let Some(payload) = &self.payload {\n            buffer << \"(\" << payload << \")\"\n        } else {\n            buffer\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_field_write.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, Identifier, PostfixTermFieldWrite, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for PostfixTermFieldWrite {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::postfix_term_field_write);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let id = Identifier::from_parse_tree(inner.next().expect(\"postfix need id\"), source);\n        let val = inner.next().map(|p| Expression::from_parse_tree(p, source));\n        Self {\n            loc: source.pointer(loc),\n            id,\n            val,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermFieldWrite {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let buffer = buffer << \".\" << &self.id;\n        if let Some(val) = &self.val {\n            buffer << \" = \" << val\n        } else {\n            buffer\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_index.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::ast::{\n    ExpressionList, PostfixTermIndex,\n    derive::Derive,\n    prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n};\n\nimpl Derive for PostfixTermIndex {\n    fn from_parse_tree(\n        p: pest::iterators::Pair<'_, crate::grammar::Rule>,\n        source: &crate::ast::SourceBuffer,\n    ) -> Self {\n        assert!(p.as_rule() == crate::grammar::Rule::postfix_term_index);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let index = inner\n            .next()\n            .map_or(ExpressionList::empty(source.pointer(loc)), |e| {\n                <ExpressionList>::from_parse_tree(e, source)\n            });\n        Self {\n            loc: source.pointer(loc),\n            index,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermIndex {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"[\" << &self.index << \"]\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_index_write.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::ast::{\n    Expression, ExpressionList, PostfixTermIndexWrite,\n    derive::Derive,\n    prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n};\n\nimpl Derive for PostfixTermIndexWrite {\n    fn from_parse_tree(\n        p: pest::iterators::Pair<'_, crate::grammar::Rule>,\n        source: &crate::ast::SourceBuffer,\n    ) -> Self {\n        assert!(p.as_rule() == crate::grammar::Rule::postfix_term_index_write);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let idx = if inner.peek().expect(\"need index\").as_rule() == crate::grammar::Rule::expr_list\n        {\n            <ExpressionList>::from_parse_tree(\n                inner.next().expect(concat!(\"need \", stringify!(idx))),\n                source,\n            )\n        } else {\n            ExpressionList::empty(source.pointer(loc))\n        };\n        let val = <Expression>::from_parse_tree(\n            inner.next().expect(concat!(\"need \", stringify!(val))),\n            source,\n        );\n        Self {\n            loc: source.pointer(loc),\n            idx,\n            val,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermIndexWrite {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"[\" << &self.idx << \"] = \" << &self.val\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_object_write.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixTermObjectWrite, PostfixTermWriteList,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for PostfixTermObjectWrite {\n    gen_from_components!(postfix_term_object_write; terms: PostfixTermWriteList);\n}\n\nimpl PrettyPrintable for PostfixTermObjectWrite {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"{\" << &self.terms << \"}\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_try_protocol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixTermTryProtocol, SourceBuffer, TryProtocolMode,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for PostfixTermTryProtocol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::postfix_term_try_protocol);\n        let loc = From::from(&p.as_span());\n        let token_rule = p\n            .into_inner()\n            .next()\n            .and_then(|inner| inner.into_inner().next())\n            .map(|inner| inner.as_rule())\n            .unwrap_or_else(|| panic!(\"? or ! expected\"));\n        let mode = match token_rule {\n            Rule::postfix_term_try_protocol_return_token => TryProtocolMode::Return,\n            Rule::postfix_term_try_protocol_assert_token => TryProtocolMode::Assert,\n            _ => panic!(\"? or ! expected\"),\n        };\n\n        Self {\n            loc: source.pointer(loc),\n            mode,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermTryProtocol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer\n            << match self.mode {\n                TryProtocolMode::Assert => \"!\",\n                TryProtocolMode::Return => \"?\",\n            }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_write.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixTermFieldWrite, PostfixTermIndexWrite, PostfixTermWrite,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nimpl Derive for PostfixTermWrite {\n    gen_from_options!(postfix_term_write; (postfix_term_field_write, PostfixTermFieldWrite), (postfix_term_index_write, PostfixTermIndexWrite));\n}\n\nimpl PrettyPrintable for PostfixTermWrite {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::PostfixTermFieldWrite(v) => v.prettyprint(buffer),\n            Self::PostfixTermIndexWrite(v) => v.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/postfix_term_write_list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixTermWrite, PostfixTermWriteList, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for PostfixTermWriteList {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::postfix_term_write_list);\n        let loc = From::from(&p.as_span());\n        let inner = p.into_inner();\n        let terms = inner\n            .map(|i| PostfixTermWrite::from_parse_tree(i, source))\n            .collect();\n        Self {\n            loc: source.pointer(loc),\n            terms,\n        }\n    }\n}\n\nimpl PrettyPrintable for PostfixTermWriteList {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write_separated_list(&self.terms, \", \")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/primary.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Primary,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nuse crate::ast::FloatLiteral;\nuse crate::ast::Identifier;\nuse crate::ast::IntLiteral;\nuse crate::ast::ListLiteral;\nuse crate::ast::ParenExpression;\nuse crate::ast::StringLiteral;\n\nimpl Derive for Primary {\n    gen_from_options!(\n        primary;\n        (int_literal, IntLiteral),\n        (fp_literal, FloatLiteral),\n        (identifier, Identifier),\n        (list_literal, ListLiteral),\n        (str_literal, StringLiteral),\n        (paren_expr, ParenExpression)\n    );\n}\n\nimpl PrettyPrintable for Primary {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::IntLiteral(il) => il.prettyprint(buffer),\n            Self::FloatLiteral(fp) => fp.prettyprint(buffer),\n            Self::Identifier(id) => id.prettyprint(buffer),\n            Self::ListLiteral(ll) => ll.prettyprint(buffer),\n            Self::StringLiteral(sl) => sl.prettyprint(buffer),\n            Self::ParenExpression(pe) => pe.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/rel_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        RelOperation, RelSymbol, ShiftOperation, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for RelOperation {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::rel);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        if inner.len() == 1 {\n            let left = ShiftOperation::from_parse_tree(inner.next().expect(\"left operand\"), source);\n            Self {\n                loc: source.pointer(loc),\n\n                left,\n                right: None,\n            }\n        } else if inner.len() == 3 {\n            let left = ShiftOperation::from_parse_tree(inner.next().expect(\"left operand\"), source);\n            let op = RelSymbol::from_parse_tree(inner.next().expect(\"rel operator\"), source);\n            let right =\n                ShiftOperation::from_parse_tree(inner.next().expect(\"right operand\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: Some((op, right)),\n            }\n        } else {\n            panic!(\"invalid rel length\");\n        }\n    }\n}\n\nimpl PrettyPrintable for RelOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let this = self.left.prettyprint(buffer);\n        if let Some(rhs) = &self.right {\n            this << &rhs.0 << &rhs.1\n        } else {\n            this\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/rel_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        RelSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for RelSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::rel_op);\n        match p.as_str() {\n            \"<\" => RelSymbol::Less,\n            \"<=\" => RelSymbol::LessEqual,\n            \">\" => RelSymbol::Greater,\n            \">=\" => RelSymbol::GreaterEqual,\n            _ => panic!(\"<=> expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for RelSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Less => \"<\",\n            Self::LessEqual => \"<=\",\n            Self::Greater => \">\",\n            Self::GreaterEqual => \">=\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/return_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, ReturnStatement, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ReturnStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::return_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let val = inner.next().map(|p| Expression::from_parse_tree(p, source));\n        Self {\n            loc: source.pointer(loc),\n            val,\n        }\n    }\n}\n\nimpl PrettyPrintable for ReturnStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let mut buffer = buffer << \"return\";\n        if let Some(val) = &self.val {\n            buffer = buffer << \" \" << val;\n        }\n        buffer << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/shift_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AddOperation, ShiftOperation, ShiftSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ShiftOperation {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::shift);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        if inner.len() == 1 {\n            let left = AddOperation::from_parse_tree(inner.next().expect(\"left operand\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: None,\n            }\n        } else if inner.len() == 3 {\n            let left = AddOperation::from_parse_tree(inner.next().expect(\"left operand\"), source);\n            let op = ShiftSymbol::from_parse_tree(inner.next().expect(\"shift operator\"), source);\n            let right = AddOperation::from_parse_tree(inner.next().expect(\"right operand\"), source);\n            Self {\n                loc: source.pointer(loc),\n                left,\n                right: Some((op, right)),\n            }\n        } else {\n            panic!(\"invalid shift length\");\n        }\n    }\n}\n\nimpl PrettyPrintable for ShiftOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        let this = self.left.prettyprint(buffer);\n        if let Some(rhs) = &self.right {\n            this << &rhs.0 << &rhs.1\n        } else {\n            this\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/shift_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        ShiftSymbol, SourceBuffer,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ShiftSymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::shift_op);\n        match p.as_str() {\n            \"<<\" => Self::Leftward,\n            \">>\" => Self::Rightward,\n            _ => panic!(\"<< or >> expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for ShiftSymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Leftward => \"<<\",\n            Self::Rightward => \">>\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AssertStatement, AssignStatement, BreakStatement, CodeBlock, ContinueStatement, EnumDecl,\n        ExpressionStatement, ForStatement, FunctionDecl, IfStatement, MatchStatement,\n        ReturnStatement, Statement, StructDecl, ThrowStatement, TryBlock, ValDeclStatement,\n        WhileStatement, WriteOpEqStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nimpl Derive for Statement {\n    gen_from_options!(\n        statement;\n        (assert_stmt, AssertStatement),\n        (break_stmt, BreakStatement),\n        (code_block, CodeBlock),\n        (continue_stmt, ContinueStatement),\n        (expr_stmt, ExpressionStatement),\n        (for_stmt, ForStatement),\n        (if_stmt, IfStatement),\n        (match_stmt, MatchStatement),\n        (return_stmt, ReturnStatement),\n        (throw_stmt, ThrowStatement),\n        (try_block, TryBlock),\n        (val_add_eq_write, WriteOpEqStatement),\n        (val_decl_stmt, ValDeclStatement),\n        (val_write_stmt, AssignStatement),\n        (while_stmt, WhileStatement),\n        (struct_decl, StructDecl),\n        (enum_decl, EnumDecl),\n        (function_decl, FunctionDecl),\n    );\n}\n\nimpl PrettyPrintable for Statement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::ValDeclStatement(v) => v.prettyprint(buffer),\n            Self::AssignStatement(a) => a.prettyprint(buffer),\n            Self::WriteOpEqStatement(w) => w.prettyprint(buffer),\n            Self::IfStatement(i) => i.prettyprint(buffer),\n            Self::MatchStatement(m) => m.prettyprint(buffer),\n            Self::WhileStatement(w) => w.prettyprint(buffer),\n            Self::ForStatement(f) => f.prettyprint(buffer),\n            Self::CodeBlock(c) => c.prettyprint(buffer),\n            Self::ReturnStatement(r) => r.prettyprint(buffer),\n            Self::ThrowStatement(t) => t.prettyprint(buffer),\n            Self::TryBlock(t) => t.prettyprint(buffer),\n            Self::AssertStatement(a) => a.prettyprint(buffer),\n            Self::ExpressionStatement(e) => e.prettyprint(buffer),\n            Self::BreakStatement(b) => b.prettyprint(buffer),\n            Self::ContinueStatement(c) => c.prettyprint(buffer),\n            Self::StructDecl(s) => s.prettyprint(buffer),\n            Self::EnumDecl(e) => e.prettyprint(buffer),\n            Self::FunctionDecl(f) => f.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/string_literal.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        SourceBuffer, StringLiteral,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\n// TODO: process string literals in the compiler code, not the parser\n// the parser has no good way to report an error, so complete the processing\n// in the compiler where we can fail on an invalid escape sequence\nfn process_string_literal(s: &str) -> String {\n    fn process_string_escapes(s: &str) -> String {\n        let mut result = String::new();\n        let mut chars = s.chars().peekable();\n\n        while let Some(c) = chars.next() {\n            if c == '\\\\' {\n                if let Some(next) = chars.peek() {\n                    match next {\n                        'n' => {\n                            result.push('\\n');\n                            chars.next();\n                        }\n                        'r' => {\n                            result.push('\\r');\n                            chars.next();\n                        }\n                        't' => {\n                            result.push('\\t');\n                            chars.next();\n                        }\n                        '\\\\' => {\n                            result.push('\\\\');\n                            chars.next();\n                        }\n                        'X' | 'x' => {\n                            let _ = chars.next();\n                            if let (Some(high), Some(low)) = (chars.next(), chars.next())\n                                && let (Some(high), Some(low)) =\n                                    (high.to_digit(16), low.to_digit(16))\n                            {\n                                result.push((high << 4 | low) as u8 as char);\n                            }\n                        }\n                        'U' | 'u' => {\n                            let _ = chars.next();\n                            if chars.peek() == Some(&'{') {\n                                let _ = chars.next();\n                                let mut hex_digits = String::new();\n                                while let Some(&next) = chars.peek() {\n                                    if next == '}' {\n                                        let _ = chars.next();\n                                        break;\n                                    } else {\n                                        hex_digits.push(chars.next().unwrap());\n                                    }\n                                }\n                                if let Ok(codepoint) = u32::from_str_radix(&hex_digits, 16)\n                                    && let Some(chr) = char::from_u32(codepoint)\n                                {\n                                    result.push(chr);\n                                }\n                            }\n                        }\n                        _ => {\n                            result.push(c);\n                        }\n                    }\n                } else {\n                    result.push(c);\n                }\n            } else {\n                result.push(c);\n            }\n        }\n\n        result\n    }\n\n    let s = &s[1..s.len() - 1];\n    process_string_escapes(s)\n}\n\nimpl Derive for StringLiteral {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::str_literal);\n        let loc = From::from(&p.as_span());\n        Self {\n            loc: source.pointer(loc),\n            value: process_string_literal(p.as_str()),\n        }\n    }\n}\n\nimpl PrettyPrintable for StringLiteral {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(&self.value)\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/struct_decl.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, Identifier, SourceBuffer, StructDecl, StructEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for StructDecl {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::struct_decl);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let name = Identifier::from_parse_tree(inner.next().expect(\"need identifier\"), source);\n        let inherits = if let Some(next) = inner.peek() {\n            if next.as_rule() == Rule::expr_list {\n                let expr_list = inner.next().unwrap();\n                expr_list\n                    .into_inner()\n                    .map(|expr| Expression::from_parse_tree(expr, source))\n                    .collect()\n            } else {\n                vec![]\n            }\n        } else {\n            vec![]\n        };\n        let mut body = vec![];\n        for next in inner {\n            let next = StructEntry::from_parse_tree(next, source);\n            body.push(next);\n        }\n        Self {\n            loc: source.pointer(loc),\n            name,\n            inherits,\n            body,\n        }\n    }\n}\n\nimpl PrettyPrintable for StructDecl {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        (buffer << \"struct \" << &self.name).write_indented_list(&self.body, \"{\\n\", \"\\n\", \"\\n}\")\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/struct_entry.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        EnumDecl, MethodDecl, MixinIncludeDecl, OperatorDecl, SourceBuffer, StructDecl,\n        StructEntry, ValDeclStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for StructEntry {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::struct_entry);\n        let content = p.into_inner().next().expect(\"needs an atom inside\");\n        match content.as_rule() {\n            Rule::method_decl => {\n                Self::Method(Box::new(MethodDecl::from_parse_tree(content, source)))\n            }\n            Rule::operator_decl => {\n                Self::Operator(Box::new(OperatorDecl::from_parse_tree(content, source)))\n            }\n            Rule::val_decl_stmt => {\n                Self::Variable(Box::new(ValDeclStatement::from_parse_tree(content, source)))\n            }\n            Rule::struct_decl => {\n                Self::Struct(Box::new(StructDecl::from_parse_tree(content, source)))\n            }\n            Rule::enum_decl => Self::Enum(Box::new(EnumDecl::from_parse_tree(content, source))),\n            Rule::mixin_include_decl => {\n                Self::MixinInclude(Box::new(MixinIncludeDecl::from_parse_tree(content, source)))\n            }\n            _ => panic!(\"invalid struct entry kind\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for StructEntry {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::Method(m) => m.prettyprint(buffer),\n            Self::Operator(o) => o.prettyprint(buffer),\n            Self::Variable(v) => v.prettyprint(buffer << \"type \"),\n            Self::Struct(s) => s.prettyprint(buffer),\n            Self::Enum(e) => e.prettyprint(buffer),\n            Self::MixinInclude(m) => m.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/ternary_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, LogOperation, SourceBuffer, TernaryExpression,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for TernaryExpression {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::ternary_expr);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let condition = LogOperation::from_parse_tree(inner.next().unwrap(), source);\n        let true_expression = Expression::from_parse_tree(inner.next().unwrap(), source);\n        let false_expression = Expression::from_parse_tree(inner.next().unwrap(), source);\n        TernaryExpression {\n            loc: source.pointer(loc),\n            condition: Box::new(condition),\n            true_expression: Box::new(true_expression),\n            false_expression: Box::new(false_expression),\n        }\n    }\n}\n\nimpl PrettyPrintable for TernaryExpression {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        self.condition.prettyprint(buffer)\n            << \" ? \"\n            << self.true_expression.as_ref()\n            << \" : \"\n            << self.false_expression.as_ref()\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/throw_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, ThrowStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for ThrowStatement {\n    gen_from_components!(throw_stmt; val: Expression);\n}\n\nimpl PrettyPrintable for ThrowStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"throw \" << &self.val << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/top_level_entry.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AssertStatement, AssignStatement, CodeBlock, EnumDecl, ExpressionStatement, ExtensionDecl,\n        ForStatement, FunctionDecl, IfStatement, ImportFromStatement, ImportStatement,\n        MatchStatement, MixinDecl, StructDecl, TopLevelEntry, TryBlock, ValDeclStatement,\n        WhileStatement, WriteOpEqStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_options,\n};\n\nimpl Derive for TopLevelEntry {\n    gen_from_options!(\n        top_level_entry;\n        (assert_stmt, AssertStatement),\n        (enum_decl, EnumDecl),\n        (expr_stmt, ExpressionStatement),\n        (extension_decl, ExtensionDecl),\n        (function_decl, FunctionDecl),\n        (import_id_stmt, ImportFromStatement),\n        (import_stmt, ImportStatement),\n        (mixin_decl, MixinDecl),\n        (struct_decl, StructDecl),\n        (val_decl_stmt, ValDeclStatement),\n        (val_write_stmt, AssignStatement),\n        (if_stmt, IfStatement),\n        (match_stmt, MatchStatement),\n        (while_stmt, WhileStatement),\n        (for_stmt, ForStatement),\n        (val_add_eq_write, WriteOpEqStatement),\n        (try_block, TryBlock),\n        (code_block, CodeBlock),\n    );\n}\n\nimpl PrettyPrintable for TopLevelEntry {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        match self {\n            Self::ValDeclStatement(v) => v.prettyprint(buffer),\n            Self::WriteOpEqStatement(w) => w.prettyprint(buffer),\n            Self::AssignStatement(a) => a.prettyprint(buffer),\n            Self::FunctionDecl(f) => f.prettyprint(buffer),\n            Self::StructDecl(s) => s.prettyprint(buffer),\n            Self::MixinDecl(m) => m.prettyprint(buffer),\n            Self::EnumDecl(e) => e.prettyprint(buffer),\n            Self::ExtensionDecl(e) => e.prettyprint(buffer),\n            Self::AssertStatement(a) => a.prettyprint(buffer),\n            Self::ExpressionStatement(e) => e.prettyprint(buffer),\n            Self::ImportStatement(i) => i.prettyprint(buffer),\n            Self::ImportFromStatement(i) => i.prettyprint(buffer),\n            Self::IfStatement(i) => i.prettyprint(buffer),\n            Self::MatchStatement(m) => m.prettyprint(buffer),\n            Self::WhileStatement(w) => w.prettyprint(buffer),\n            Self::ForStatement(f) => f.prettyprint(buffer),\n            Self::CodeBlock(c) => c.prettyprint(buffer),\n            Self::TryBlock(t) => t.prettyprint(buffer),\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/try_block.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, Identifier, TryBlock,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for TryBlock {\n    gen_from_components!(try_block; body: CodeBlock, id: Identifier, catch: CodeBlock);\n}\n\nimpl PrettyPrintable for TryBlock {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"try \" << &self.body << \" catch (\" << &self.id << \") \" << &self.catch\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/try_unwrap_expression.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        Expression, LogOperation, SourceBuffer, TryUnwrapExpression,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for TryUnwrapExpression {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::try_unwrap_expr);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let left = LogOperation::from_parse_tree(inner.next().unwrap(), source);\n        let right = Expression::from_parse_tree(inner.next().unwrap(), source);\n        TryUnwrapExpression {\n            loc: source.pointer(loc),\n            left: Box::new(left),\n            right: Box::new(right),\n        }\n    }\n}\n\nimpl PrettyPrintable for TryUnwrapExpression {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        self.left.prettyprint(buffer) << \" ?? \" << self.right.as_ref()\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/unary_operation.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        PostfixExpression, PostfixRvalue, SourceBuffer, UnaryOperation, UnarySymbol,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for UnaryOperation {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::unary);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        if inner.len() == 1 {\n            let postfix = inner.next().expect(\"need postfix\");\n            let postfix = PostfixRvalue::from_parse_tree(postfix, source);\n            Self {\n                loc: source.pointer(loc),\n                operand: None,\n                postfix,\n            }\n        } else if inner.len() == 2 {\n            let operand = inner.next().expect(\"need operand\");\n            let operand = UnarySymbol::from_parse_tree(operand, source);\n            let postfix = inner.next().expect(\"need postfix\");\n            let postfix = PostfixRvalue::from_parse_tree(postfix, source);\n\n            if operand == UnarySymbol::Minus\n                && postfix.expr.terms.is_empty()\n                && let Some(il) = postfix.expr.base.as_int_literal()\n                && il.base == crate::ast::IntLiteralBase::Decimal\n            {\n                let new_val = if il.val.starts_with('-') {\n                    il.val.strip_prefix('-').unwrap_or(&il.val).to_string()\n                } else {\n                    format!(\"-{}\", il.val)\n                };\n                let new_il = crate::ast::IntLiteral {\n                    loc: il.loc.clone(),\n                    base: il.base.clone(),\n                    val: new_val,\n                };\n                return Self {\n                    loc: source.pointer(loc),\n                    operand: None,\n                    postfix: PostfixRvalue {\n                        loc: postfix.loc.clone(),\n                        expr: PostfixExpression {\n                            loc: postfix.expr.loc.clone(),\n                            base: crate::ast::Primary::IntLiteral(new_il),\n                            terms: vec![],\n                        },\n                    },\n                };\n            }\n\n            Self {\n                loc: source.pointer(loc),\n                operand: Some(operand),\n                postfix,\n            }\n        } else {\n            panic!(\"unexpected unary operation structure\");\n        }\n    }\n}\n\nimpl PrettyPrintable for UnaryOperation {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.operand << &self.postfix\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/unary_symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        SourceBuffer, UnarySymbol,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for UnarySymbol {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, _: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::unary_op);\n        match p.as_str() {\n            \"!\" => Self::Exclamation,\n            \"-\" => Self::Minus,\n            _ => panic!(\"! or - expected\"),\n        }\n    }\n}\n\nimpl PrettyPrintable for UnarySymbol {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer.write(match self {\n            Self::Exclamation => \"!\",\n            Self::Minus => \"-\",\n        })\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/val_decl_entry.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        DeclarationId, Expression, ValDeclEntry,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for ValDeclEntry {\n    gen_from_components!(val_decl_entry; id: DeclarationId, val: Expression);\n}\n\nimpl PrettyPrintable for ValDeclEntry {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.id << \" = \" << &self.val\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/val_decl_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        SourceBuffer, ValDeclEntry, ValDeclStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for ValDeclStatement {\n    fn from_parse_tree(p: pest::iterators::Pair<'_, Rule>, source: &SourceBuffer) -> Self {\n        assert!(p.as_rule() == Rule::val_decl_stmt);\n        let loc = From::from(&p.as_span());\n        let decls = p\n            .into_inner()\n            .map(|i| ValDeclEntry::from_parse_tree(i, source))\n            .collect::<Vec<_>>();\n        Self {\n            loc: source.pointer(loc),\n            decls,\n        }\n    }\n}\n\nimpl PrettyPrintable for ValDeclStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        (buffer << \"val \").write_separated_list(&self.decls, \", \") << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/while_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        CodeBlock, ElsePiece, Expression, WhileStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    grammar::Rule,\n};\n\nimpl Derive for WhileStatement {\n    fn from_parse_tree(\n        p: pest::iterators::Pair<'_, crate::grammar::Rule>,\n        source: &crate::ast::SourceBuffer,\n    ) -> Self {\n        assert!(p.as_rule() == Rule::while_stmt);\n        let loc = From::from(&p.as_span());\n        let mut inner = p.into_inner();\n        let cond = Expression::from_parse_tree(inner.next().expect(\"need condition\"), source);\n        let then = CodeBlock::from_parse_tree(inner.next().expect(\"need then block\"), source);\n        let els = inner\n            .next()\n            .map(|else_p| ElsePiece::from_parse_tree(else_p, source));\n\n        Self {\n            loc: source.pointer(loc),\n            cond,\n            then,\n            els,\n        }\n    }\n}\n\nimpl PrettyPrintable for WhileStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << \"while \" << &self.cond << &self.then\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/nodes/write_op_eq_statement.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    ast::{\n        AddEqSymbol, Expression, PostfixExpression, WriteOpEqStatement,\n        derive::Derive,\n        prettyprint::{PrettyPrintable, printout_accumulator::PrintoutAccumulator},\n    },\n    gen_from_components,\n};\n\nimpl Derive for WriteOpEqStatement {\n    gen_from_components!(val_add_eq_write; id: PostfixExpression, op: AddEqSymbol, val: Expression);\n}\n\nimpl PrettyPrintable for WriteOpEqStatement {\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << &self.id << &self.op << &self.val << \";\"\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/prettyprint/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\npub mod printout_accumulator;\n\nuse crate::ast::prettyprint::printout_accumulator::PrintoutAccumulator;\n\npub trait PrettyPrintable {\n    fn prettyprint(\n        &self,\n        buffer: printout_accumulator::PrintoutAccumulator,\n    ) -> printout_accumulator::PrintoutAccumulator;\n}\n\nimpl<T> PrettyPrintable for Box<T>\nwhere\n    T: PrettyPrintable,\n{\n    fn prettyprint(&self, buffer: PrintoutAccumulator) -> PrintoutAccumulator {\n        buffer << self.as_ref()\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/ast/prettyprint/printout_accumulator.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::ast::prettyprint::PrettyPrintable;\n\n#[derive(Default)]\npub struct PrintoutAccumulator {\n    buffer: String,\n    depth: usize,\n}\n\nimpl PrintoutAccumulator {\n    pub(crate) fn indent_more(mut self) -> Self {\n        self.depth += 1;\n        self\n    }\n\n    pub(crate) fn indent_less(mut self) -> Self {\n        if self.depth > 0 {\n            self.depth -= 1;\n        }\n        self\n    }\n\n    pub(crate) fn write(mut self, text: &str) -> Self {\n        if self.depth == 0 || text.find('\\n').is_none() {\n            self.buffer.push_str(text);\n        } else {\n            for ch in text.chars() {\n                self.buffer.push(ch);\n                if ch == '\\n' {\n                    self.buffer.push_str(&\" \".repeat(self.depth * 4));\n                }\n            }\n        }\n        self\n    }\n\n    pub(crate) fn write_indented_list<T: PrettyPrintable + std::fmt::Debug>(\n        self,\n        values: &[T],\n        prefix: &str,\n        sep: &str,\n        suffix: &str,\n    ) -> Self {\n        let mut this = self.indent_more().write(prefix);\n        let mut first = true;\n        for value in values {\n            if first {\n                first = false;\n            } else {\n                this = this.write(sep);\n            }\n            this = value.prettyprint(this);\n        }\n        this.indent_less().write(suffix)\n    }\n\n    pub(crate) fn write_separated_list<T: PrettyPrintable + std::fmt::Debug>(\n        self,\n        values: &[T],\n        sep: &str,\n    ) -> Self {\n        let mut first = true;\n        let mut this = self;\n        for value in values {\n            if first {\n                first = false;\n            } else {\n                this = this.write(sep);\n            }\n            this = value.prettyprint(this);\n        }\n        this\n    }\n\n    pub fn value(&self) -> String {\n        self.buffer.clone()\n    }\n}\n\nimpl<'a, T: PrettyPrintable> std::ops::Shl<&'a T> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, item: &'a T) -> Self::Output {\n        item.prettyprint(self)\n    }\n}\n\nimpl<'a> std::ops::Shl<&'a str> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, text: &'a str) -> Self::Output {\n        self.write(text)\n    }\n}\n\nimpl std::ops::Shl<String> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, text: String) -> Self::Output {\n        self.write(&text)\n    }\n}\n\nimpl std::ops::Shl<&i64> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: &i64) -> Self::Output {\n        self.write(&n.to_string())\n    }\n}\n\nimpl std::ops::Shl<f64> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: f64) -> Self::Output {\n        self.write(&n.to_string())\n    }\n}\n\nimpl std::ops::Shl<usize> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: usize) -> Self::Output {\n        self.write(&n.to_string())\n    }\n}\n\nimpl std::ops::Shl<u32> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: u32) -> Self::Output {\n        self.write(&n.to_string())\n    }\n}\n\nimpl std::ops::Shl<u16> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: u16) -> Self::Output {\n        self.write(&n.to_string())\n    }\n}\n\nimpl std::ops::Shl<u8> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: u8) -> Self::Output {\n        self.write(&n.to_string())\n    }\n}\n\nimpl std::ops::Shl<&usize> for PrintoutAccumulator {\n    type Output = Self;\n\n    fn shl(self, n: &usize) -> Self::Output {\n        self.write(&format!(\"{n}\"))\n    }\n}\n\nimpl<'a, T> std::ops::Shl<&'a Option<T>> for PrintoutAccumulator\nwhere\n    T: PrettyPrintable,\n{\n    type Output = Self;\n\n    fn shl(self, val: &'a Option<T>) -> Self::Output {\n        if let Some(val) = val {\n            val.prettyprint(self)\n        } else {\n            self\n        }\n    }\n}\n"
  },
  {
    "path": "parser-lib/src/grammar/grammar.pest",
    "content": "WHITESPACE = _{ \" \" | \"\\n\" | \"\\t\" }\nCOMMENT    = _{ \"#\" ~ (!\"\\n\" ~ ANY)* }\n\n// this should only matter for keywords that take an expression\nkeywords = _{ \"assert\" | \"else\" | \"elsif\" | \"extension\" | \"if\" | \"include\" | \"match\" | \"return\" | \"throw\" | \"while\" }\n\nidentifier_start = @{ (XID_START | EMOJI_PRESENTATION | \"_\" | \"$\") }\nidentifier_next  = @{ (XID_CONTINUE | EMOJI_PRESENTATION | \"_\" | \"$\") }\nidentifier       = @{ !(keywords ~ !identifier_next) ~ !(\"__\" ~ identifier_next*) ~ identifier_start ~ identifier_next* }\n\nident_list = { identifier ~ (\",\" ~ identifier)* ~ \",\"? }\n\nhex_int_literal = @{ \"0x\" ~ ASCII_HEX_DIGIT+ ~ (\"_\" ~ ASCII_HEX_DIGIT+)* }\noct_int_literal = @{ \"0o\" ~ ASCII_OCT_DIGIT+ ~ (\"_\" ~ ASCII_OCT_DIGIT+)* }\nbin_int_literal = @{ \"0b\" ~ ASCII_BIN_DIGIT+ ~ (\"_\" ~ ASCII_BIN_DIGIT+)* }\ndec_int_literal = @{ \"-\"? ~ ASCII_DIGIT+ ~ (\"_\" ~ ASCII_DIGIT+)* }\nint_literal     =  { hex_int_literal | oct_int_literal | bin_int_literal | dec_int_literal }\n\nfp_literal = @{ \"-\"? ~ ASCII_DIGIT+ ~ \".\" ~ ASCII_DIGIT+ ~ exp_part? ~ \"f\"? }\nexp_part   =  { (\"e\" | \"E\") ~ (\"+\" | \"-\")? ~ ASCII_DIGIT+ }\n\nstr_literal_dbl_qt = @{ \"\\\"\" ~ (!\"\\\"\" ~ ANY)* ~ \"\\\"\" }\nstr_literal_sgl_qt = @{ \"'\" ~ (!\"'\" ~ ANY)* ~ \"'\" }\nstr_literal        = @{ str_literal_dbl_qt | str_literal_sgl_qt }\n\nlist_literal = { \"[\" ~ expr_list? ~ \"]\" }\n\nexpr_list = { expression ~ (\",\" ~ expression)* ~ \",\"? }\n\nparen_expr = { \"(\" ~ expression ~ \")\" }\nprimary    = { identifier | fp_literal | str_literal | int_literal | list_literal | paren_expr }\n\npostfix_term_field_write = { \".\" ~ identifier ~ (\"=\" ~ expression)? }\npostfix_term_index_write = { \"[\" ~ expr_list? ~ \"]\" ~ \"=\" ~ expression }\n\npostfix_term_write = {\n    postfix_term_field_write\n  | postfix_term_index_write\n}\n\npostfix_term_write_list = { postfix_term_write ~ (\",\" ~ postfix_term_write)* ~ \",\"? }\n\npostfix_term_attrib       = { \".\" ~ identifier }\npostfix_term_index        = { \"[\" ~ expr_list? ~ \"]\" }\npostfix_term_call         = { \"(\" ~ expr_list? ~ \")\" }\npostfix_term_object_write = { \"{\" ~ postfix_term_write_list ~ \"}\" }\npostfix_term_enum_case    = { \"::\" ~ identifier ~ (\"(\" ~ expression ~ \")\")? }\nternary_guard = { ternary_guard_start ~ ternary_guard_item* ~ \":\" }\nternary_guard_start = _{\n    identifier\n  | fp_literal\n  | str_literal\n  | int_literal\n  | \"(\" ~ ternary_guard_inner* ~ \")\"\n  | \"[\" ~ ternary_guard_inner* ~ \"]\"\n  | \"!\"\n  | \"-\"\n  | \"|\"\n}\nternary_guard_item = _{\n    str_literal\n  | \"(\" ~ ternary_guard_inner* ~ \")\"\n  | \"[\" ~ ternary_guard_inner* ~ \"]\"\n  | \"{\" ~ ternary_guard_inner* ~ \"}\"\n  | !(\":\" | \";\" | \",\" | \")\" | \"]\" | \"}\") ~ ANY\n}\nternary_guard_inner = _{\n    str_literal\n  | \"(\" ~ ternary_guard_inner* ~ \")\"\n  | \"[\" ~ ternary_guard_inner* ~ \"]\"\n  | \"{\" ~ ternary_guard_inner* ~ \"}\"\n  | !(\")\" | \"]\" | \"}\") ~ ANY\n}\ntry_unwrap_guard = { \"?\" ~ expression }\npostfix_term_try_protocol_assert_token = @{ \"!\" ~ !\"=\" }\npostfix_term_try_protocol_return_token = @{ \"?\" }\npostfix_term_try_protocol_assert = { postfix_term_try_protocol_assert_token }\npostfix_term_try_protocol_return = { postfix_term_try_protocol_return_token ~ !ternary_guard ~ !try_unwrap_guard }\npostfix_term_try_protocol = {\n    postfix_term_try_protocol_assert\n  | postfix_term_try_protocol_return\n}\npostfix_term              = {\n    postfix_term_object_write\n  | postfix_term_enum_case\n  | postfix_term_attrib\n  | postfix_term_index\n  | postfix_term_call\n  | postfix_term_try_protocol\n}\n\npostfix_lv = { primary ~ postfix_term* }\npostfix_rv = { postfix_lv }\n\nunary_op = @{ \"!\" | \"-\" }\nunary    =  { unary_op? ~ postfix_rv }\n\nmul_op = @{ \"*\" | \"/\" | \"%\" }\nmul    =  { unary ~ (mul_op ~ unary)* }\n\nadd_op = @{ \"+\" | \"-\" }\nadd    =  { mul ~ (add_op ~ mul)* }\n\nshift_op = @{ \"<<\" | \">>\" }\nshift    =  { add ~ (shift_op ~ add)? }\n\nrel_op = @{ \"<=\" | \"<\" | \">=\" | \">\" }\nrel    =  { shift ~ (rel_op ~ shift)? }\n\ncomp_op = @{ \"==\" | \"!=\" | \"isa\" }\ncomp    =  { rel ~ (comp_op ~ rel)? }\n\nlog_op = @{ \"&&\" | \"||\" | \"^\" | \"&\" | \"|\" }\nlog    =  { comp ~ (log_op ~ comp)* }\n\ntry_unwrap_expr = { log ~ \"??\" ~ expression }\n\nternary_expr = { log ~ \"?\" ~ expression ~ \":\" ~ expression }\n\nlambda_f_body = { expression | code_block }\nlambda_f      = { \"|\" ~ arg_list ~ \"|\" ~ \"=>\" ~ lambda_f_body }\n\nexpression = { ternary_expr | lambda_f | try_unwrap_expr | log }\n\ndecl_id = { identifier ~ (\":\" ~ expression)? }\n\nval_decl_entry = { decl_id ~ \"=\" ~ expression }\nval_decl_stmt  = { \"val\" ~ val_decl_entry ~ (\",\" ~ val_decl_entry)* ~ \";\" }\nval_write_stmt = { postfix_lv ~ (\",\" ~ postfix_lv)* ~ \"=\" ~ expression ~ (\",\" ~ expression)* ~ \";\" }\n\nadd_op_eq        = @{ \"+=\" | \"-=\" | \"*=\" | \"/=\" | \"%=\" | \"<<=\" | \">>=\" }\nval_add_eq_write =  { postfix_lv ~ add_op_eq ~ expression ~ \";\" }\n\nif_cond_piece = { expression ~ code_block }\nif_piece      = { \"if\" ~ if_cond_piece }\nelsif_piece   = { \"elsif\" ~ if_cond_piece }\nelse_piece    = { \"else\" ~ code_block }\nif_stmt       = { if_piece ~ elsif_piece* ~ else_piece? }\n\nmatch_pattern_comp      = { comp_op ~ expression }\nmatch_pattern_rel       = { rel_op ~ expression }\nmatch_pattern_enum_case = { \"case\" ~ identifier ~ (\"(\" ~ decl_id ~ \")\")? }\nmatch_pattern           = { match_pattern_enum_case | match_pattern_comp | match_pattern_rel }\nmatch_rule              = { match_pattern ~ (\"and\" ~ match_pattern)* ~ \"=>\" ~ code_block }\nmatch_stmt              = { \"match\" ~ expression ~ \"{\" ~ match_rule ~ (\",\"? ~ match_rule)* ~ \",\"? ~ \"}\" ~ else_piece? }\n\nwhile_stmt = { \"while\" ~ expression ~ code_block ~ else_piece? }\nfor_stmt   = { \"for\" ~ identifier ~ \"in\" ~ expression ~ code_block ~ else_piece? }\n\nreturn_stmt = { \"return\" ~ expression? ~ \";\" }\nassert_stmt = { \"assert\" ~ expression ~ \";\" }\n\nbreak_stmt    = { \"break\" ~ \";\" }\ncontinue_stmt = { \"continue\" ~ \";\" }\nexpr_stmt     = { expression? ~ \";\" }\n\nthrow_stmt = { \"throw\" ~ expression ~ \";\" }\n\nstatement = {\n    break_stmt\n  | continue_stmt\n  | expr_stmt\n  | assert_stmt\n  | val_write_stmt\n  | val_decl_stmt\n  | val_add_eq_write\n  | if_stmt\n  | match_stmt\n  | while_stmt\n  | for_stmt\n  | throw_stmt\n  | return_stmt\n  | code_block\n  | try_block\n  | struct_decl\n  | enum_decl\n  | function_decl\n}\n\ncode_block = { \"{\" ~ (statement)* ~ \"}\" }\ntry_block  = { \"try\" ~ code_block ~ \"catch\" ~ identifier ~ code_block }\n\nvararg_marker = { \"...\" ~ \",\"? }\narg_decl      = { decl_id ~ (\"=\" ~ expression)? }\narg_list      = { (arg_decl ~ (\",\" ~ arg_decl)* ~ \",\"?)? ~ vararg_marker? }\nfunction_body = { code_block | (\"=\" ~ expression ~ \";\") }\nfunction_decl = { \"func\" ~ identifier ~ \"(\" ~ arg_list? ~ \")\" ~ function_body }\n\nmethod_access = @{ \"instance\" | \"type\" }\nmethod_decl   =  { method_access? ~ \"func\" ~ identifier ~ \"(\" ~ arg_list? ~ \")\" ~ function_body }\n\noperator_direction = @{ \"reverse\" }\noperator_symbol    = @{ \"+\" | \"u-\" | \"-\" | \"*\" | \"/\" | \"%\" | \"<<\" | \">>\" | \"==\" | \"<=\" | \">=\" | \"<\" | \">\" | \"&\" | \"|\" | \"^\" | \"()\" | \"[]=\" | \"[]\" }\noperator_decl      =  { operator_direction? ~ \"operator\" ~ operator_symbol ~ \"(\" ~ arg_list? ~ \")\" ~ function_body }\n\nmixin_decl = { \"mixin\" ~ identifier ~ \"{\" ~ struct_entry* ~ \"}\" }\n\nmixin_include_decl = { \"include\" ~ expression }\n\nstruct_entry = { method_decl | operator_decl | \"type\" ~ val_decl_stmt | mixin_include_decl | struct_decl | enum_decl }\n\nstruct_decl = { \"struct\" ~ identifier ~ (\":\" ~ expr_list)? ~ \"{\" ~ struct_entry* ~ \"}\" }\nextension_decl = { \"extension\" ~ expression ~ (\":\" ~ expr_list)? ~ \"{\" ~ struct_entry* ~ \"}\" }\n\nenum_case_decl  = { \"case\" ~ identifier ~ (\"(\" ~ expression ~ \")\")? }\nenum_decl_entry = { (enum_case_decl | struct_entry) ~ \",\"? }\n\nenum_decl = { \"enum\" ~ identifier ~ \"{\" ~ enum_decl_entry* ~ \"}\" }\n\nimport_all     = { \"*\" }\nimport_target  = { ident_list | import_all }\nimport_path    = { identifier ~ (\".\" ~ identifier)* }\nimport_stmt    = { \"import\" ~ import_path ~ \";\" }\nimport_id_stmt = { \"import\" ~ import_target ~ \"from\" ~ import_path ~ \";\" }\n\ntop_level_entry = {\n    import_id_stmt\n  | import_stmt\n  | expr_stmt\n  | val_write_stmt\n  | val_decl_stmt\n  | val_add_eq_write\n  | struct_decl\n  | mixin_decl\n  | enum_decl\n  | extension_decl\n  | function_decl\n  | assert_stmt\n  | if_stmt\n  | match_stmt\n  | while_stmt\n  | for_stmt\n  | code_block\n  | try_block\n}\n\nmodule_flag  = { \"flag:\" ~ identifier ~ (\"(\" ~ str_literal ~ \")\")? ~ \";\" }\nmodule_flags = { module_flag* }\n\nmodule = { SOI ~ module_flags? ~ top_level_entry* ~ EOI }\n"
  },
  {
    "path": "parser-lib/src/grammar/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse pest_derive::Parser;\n\n#[derive(Parser)]\n#[grammar = \"grammar/grammar.pest\"]\npub struct HaxbyParser;\n"
  },
  {
    "path": "parser-lib/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub mod ast;\npub mod grammar;\n"
  },
  {
    "path": "pgo",
    "content": "#!/bin/sh\n\nSELF_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\nARIA_LIB_DIR=\"${ARIA_LIB_DIR:-${SELF_DIR}/lib}\"\nRUST_MIN_STACK=16777216\n\ncargo install cargo-pgo && rustup component add llvm-tools-preview\n\noutput=$(cargo pgo build -- --profile pgo 2>&1)\n\naria_bin=$(printf \"%s\\n\" \"$output\" | sed -n 's/.* Now run \\(.*\\/aria\\) on your workload.*/\\1/p')\n\n# TODO: write a more interesting benchmark workload\nRUST_MIN_STACK=${RUST_MIN_STACK} ARIA_LIB_DIR=${ARIA_LIB_DIR} ${aria_bin} ${SELF_DIR}/examples/sieve.aria\n\ncargo pgo optimize build -- --profile pgo\n\naria_parent=$(dirname \"$aria_bin\")\njson=false\nfor arg in \"$@\"; do\n    if [ \"$arg\" = \"--json\" ]; then json=true; break; fi\ndone\n\n# emit JSON so that automated tools can process the path to the optimized binary\n# e.g. path=`jq -r '.output_path' /path/to/json.out`\nif [ \"$json\" = true ]; then\n    printf '{\"output_path\":\"%s\"}\\n' \"$aria_parent\"\nelse\n    printf 'Run PGO optimized Aria as ARIA_LIB_DIR=\"%s\" %s\\n' \"${ARIA_LIB_DIR}\" \"${aria_bin}\"\nfi\n"
  },
  {
    "path": "run_doc_script_tests.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nSELF_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nARIA_BUILD_CONFIG=\"${ARIA_BUILD_CONFIG:-dev}\"\nARIA_LIB_DIR=\"${ARIA_LIB_DIR:-${SELF_DIR}/lib:${SELF_DIR}/lib-test}\"\nARIA_TEST_DIR=\"${ARIA_TEST_DIR:-${SELF_DIR}/tests}\"\nRUST_MIN_STACK=16777216\n\nprint_help() {\n    cat <<'EOF'\nUsage: run_doc_script_tests.sh INPUT_FILE [OUTDIR]\n\nExtract all ```aria fenced code blocks from INPUT_FILE into numbered\nOUTDIR/*.aria files, run each of them with the local 'aria' binary,\nand clean up afterwards.\n\nIf OUTDIR is not provided, a temporary directory under /tmp is created\nand removed automatically.\nEOF\n}\n\nif [ \"$#\" -eq 0 ]; then\n    print_help\n    exit 1\nfi\n\nif [ \"$#\" -eq 1 ] && [ \"${1-}\" = \"--help\" ]; then\n    print_help\n    exit 0\nfi\n\ninfile=\"$1\"\n\nif [ \"${2-}\" != \"\" ]; then\n    outdir=\"$2\"\n    cleanup_outdir=0\nelse\n    outdir=\"$(mktemp -d /tmp/aria_manual_tests.XXXXXX)\"\n    cleanup_outdir=1\nfi\n\nmkdir -p \"$outdir\"\n\nawk -P -v outdir=\"$outdir\" '\nBEGIN { inn=0; idx=0; }\n\n# start fence: ```aria\n/^[[:space:]]*```aria[[:space:]]*$/ {\n    inn=1\n    fname = outdir \"/\" idx \".aria\"\n    print \"\" > fname\n    idx++\n    next\n}\n\n# end fence: ```\n/^[[:space:]]*```[[:space:]]*$/ {\n    if (inn==1) {\n        inn=0\n        close(fname)\n        next\n    }\n}\n\ninn==1 { print >> fname }\n' \"$infile\"\n\n[ -d \"$outdir\" ] || exit 0\n\nfor f in \"$outdir\"/*.aria; do\n    [ -f \"$f\" ] || continue\n    echo \"Running test $f\"\n    \"${SELF_DIR}/aria\" \"$f\"\ndone\n\nif [ \"$cleanup_outdir\" -eq 1 ]; then\n    rm -rf \"$outdir\"\nfi\n"
  },
  {
    "path": "t",
    "content": "#!/usr/bin/env bash\nset -e\n\nSELF_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nARIA_BUILD_CONFIG=\"${ARIA_BUILD_CONFIG:-dev}\"\nARIA_LIB_DIR=\"${ARIA_LIB_DIR:-${SELF_DIR}/lib:${SELF_DIR}/lib-test}\"\nARIA_TEST_DIR=\"${ARIA_TEST_DIR:-${SELF_DIR}/tests}\"\nRUST_MIN_STACK=16777216\n\ncargo build --workspace --profile \"$ARIA_BUILD_CONFIG\"\n\nARIA_LIB_DIR=\"$ARIA_LIB_DIR\" cargo test --profile \"$ARIA_BUILD_CONFIG\" --package vm-lib\nARIA_LIB_DIR=\"$ARIA_LIB_DIR\" cargo test --profile \"$ARIA_BUILD_CONFIG\" --package aria-bin\n\nset +e\nARIA_LIB_DIR=\"$ARIA_LIB_DIR\" cargo run --profile \"$ARIA_BUILD_CONFIG\" --package aria-bin -- vm-lib/src/builtins/test_exit.aria\nEXIT_CODE=$?\nset -e\nif [ $EXIT_CODE -ne 42 ]; then\n    echo \"❌ test_exit.aria exited with code $EXIT_CODE, expected 42\"\n    exit 1\nelse\n    echo \"✅ test_exit.aria exited with code $EXIT_CODE\"\nfi\n\nset +e\nARIA_LIB_DIR=\"$ARIA_LIB_DIR\" cargo run --profile \"$ARIA_BUILD_CONFIG\" --package aria-bin -- aria-bin/test_assert.aria\nEXIT_CODE=$?\nset -e\nif [ $EXIT_CODE -ne 1 ]; then\n    echo \"❌ test_assert.aria exited with code $EXIT_CODE, expected 1\"\n    exit 1\nelse\n    echo \"✅ test_assert.aria exited with code $EXIT_CODE\"\nfi\n\nset +e\nARIA_LIB_DIR=\"$ARIA_LIB_DIR\" cargo run --profile \"$ARIA_BUILD_CONFIG\" --package aria-bin -- aria-bin/test_uncaught_exception.aria\nEXIT_CODE=$?\nset -e\nif [ $EXIT_CODE -ne 1 ]; then\n    echo \"❌ test_uncaught_exception.aria exited with code $EXIT_CODE, expected 1\"\n    exit 1\nelse\n    echo \"✅ test_uncaught_exception.aria exited with code $EXIT_CODE\"\nfi\n\nset +e\nERROR_REPORTING_TEMPLATE=\"$SELF_DIR\"/aria-bin/src/error_reporting_test/expected.txt\nERROR_REPORTING_OUTPUT=$(ARIA_LIB_DIR_EXTRA=\"$SELF_DIR\"/aria-bin/src/error_reporting_test \\\n          ARIA_LIB_DIR=\"$ARIA_LIB_DIR\" \\\n          cargo run --profile \"$ARIA_BUILD_CONFIG\" \\\n          --package aria-bin -- \\\n          \"$SELF_DIR\"/aria-bin/src/error_reporting_test/main.aria 2>&1)\nset -e\necho \"$ERROR_REPORTING_OUTPUT\" | awk '\n  match($0, /\\/[^[:space:]]+:[0-9]+:[0-9]+/) {\n    path = substr($0, RSTART, RLENGTH)\n    n = split(path, parts, \"/\")\n    print parts[n]\n  }\n' | diff -u \"$ERROR_REPORTING_TEMPLATE\" - && echo \"OK\" || { echo \"Mismatch - actual output ${ERROR_REPORTING_OUTPUT}\"; exit 1; }\n\nARIA_TEST_DIR=\"$ARIA_TEST_DIR\" \\\nARIA_LIB_DIR=\"$ARIA_LIB_DIR\" \\\nRUST_MIN_STACK=\"$RUST_MIN_STACK\" \\\ncargo run --profile \"$ARIA_BUILD_CONFIG\" --package test-bin -- --path \"tests/**/*.aria\" --verbose \"$@\"\n"
  },
  {
    "path": "test-bin/Cargo.toml",
    "content": "[package]\nname = \"test-bin\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[dependencies]\nariadne = { git = \"https://github.com/zesterer/ariadne.git\", rev=\"b60b500\" }\nclap = { version = \"4.5.57\", features = [\"derive\"] }\nglob = \"0.3.3\"\nrayon = \"1.11.0\"\nparser-lib = { path = \"../parser-lib\" }\ncompiler-lib = { path = \"../compiler-lib\" }\nvm-lib = { path = \"../vm-lib\" }\nregex = \"1.12.2\"\nonce_cell = \"1.21.3\"\nenum-as-inner = \"0.7.0\"\n\n[[bin]]\nname = \"test\"\npath = \"src/main.rs\"\n"
  },
  {
    "path": "test-bin/src/main.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::{\n    collections::HashSet,\n    fmt::Display,\n    process::{ExitCode, Termination, exit},\n    time::{Duration, Instant},\n};\n\nuse aria_compiler::compile_from_source;\nuse aria_parser::ast::SourceBuffer;\nuse clap::Parser;\nuse enum_as_inner::EnumAsInner;\nuse glob::Paths;\nuse haxby_vm::vm::VirtualMachine;\nuse rayon::prelude::*;\nuse regex::Regex;\n\n#[derive(clap::ValueEnum, Clone, Debug, Default)]\nenum SortBy {\n    #[default]\n    Name,\n    Duration,\n}\n\n#[derive(Parser, Debug)]\n#[command(author, version, about)]\nstruct Args {\n    /// A glob expression resulting in which test files to run\n    #[arg(long)]\n    path: String,\n    #[arg(long)]\n    /// Print additional output information\n    verbose: bool,\n    #[arg(long)]\n    /// Run tests sequentially instead of in parallel\n    sequential: bool,\n    #[arg(long = \"fail-fast\")]\n    /// Exit when any test fails, instead of running the entire suite\n    fail_fast: bool,\n    #[arg(long, value_enum, default_value_t)]\n    /// Sort test results by name or duration\n    sort_by: SortBy,\n    /// Skip tests whose file name matches any of these regexes. May repeat.\n    #[arg(long = \"skip-pattern\")]\n    skip_pattern: Vec<String>,\n}\n\n#[derive(Clone, EnumAsInner)]\nenum TestCaseOutcome {\n    Pass,\n    Fail(String),\n    #[allow(dead_code)]\n    XFail(String),\n}\n\nimpl TestCaseOutcome {\n    fn result_emoji(&self) -> &'static str {\n        match self {\n            TestCaseOutcome::Pass => \"✅\",\n            TestCaseOutcome::Fail(_) => \"❌\",\n            TestCaseOutcome::XFail(_) => \"⚠️ \",\n        }\n    }\n\n    fn display_error_reason(&self) -> String {\n        if let Some(reason) = self.as_fail() {\n            format!(\"[{}]\", reason)\n        } else {\n            String::new()\n        }\n    }\n}\n\n#[derive(Clone)]\nstruct TestCaseResult {\n    test: String,\n    duration: Duration,\n    result: TestCaseOutcome,\n}\n\nimpl TestCaseResult {\n    fn pass(test: &str, duration: Duration) -> Self {\n        Self {\n            test: test.to_owned(),\n            duration,\n            result: TestCaseOutcome::Pass,\n        }\n    }\n\n    fn fail(test: &str, duration: Duration, reason: String) -> Self {\n        Self {\n            test: test.to_owned(),\n            duration,\n            result: TestCaseOutcome::Fail(reason),\n        }\n    }\n\n    fn xfail(test: &str, duration: Duration, reason: String) -> Self {\n        Self {\n            test: test.to_owned(),\n            duration,\n            result: TestCaseOutcome::XFail(reason),\n        }\n    }\n}\n\nimpl Display for TestCaseResult {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"{} {} {} [in {}.{:03} seconds]\",\n            self.result.result_emoji(),\n            self.test,\n            self.result.display_error_reason(),\n            self.duration.as_secs(),\n            self.duration.subsec_millis()\n        )\n    }\n}\n\nfn should_skip_file_name(path: &std::path::Path, skip_regex: &[Regex]) -> bool {\n    let Some(fname) = path.file_name().and_then(|s| s.to_str()) else {\n        return false;\n    };\n    skip_regex.iter().any(|re| re.is_match(fname))\n}\n\nfn parse_tags_from_file(path: &str) -> HashSet<String> {\n    let mut tags = HashSet::new();\n    let Ok(text) = std::fs::read_to_string(path) else {\n        return tags;\n    };\n\n    static TAGS_RE: once_cell::sync::Lazy<Regex> =\n        once_cell::sync::Lazy::new(|| Regex::new(r\"(?i)^\\s*###\\s*TAGS:\\s*(.+)\\s*$\").unwrap());\n\n    for line in text.lines() {\n        if let Some(cap) = TAGS_RE.captures(line)\n            && let Some(list) = cap.get(1)\n        {\n            for t in list.as_str().split(',') {\n                let t = t.trim();\n                if !t.is_empty() {\n                    tags.insert(t.to_ascii_uppercase());\n                }\n            }\n        }\n    }\n    tags\n}\n\nfn run_test_from_pattern(path: &str) -> TestCaseResult {\n    let tags = parse_tags_from_file(path);\n    let start_wall = Instant::now();\n\n    let run_once = || -> TestCaseResult {\n        let start = Instant::now();\n\n        let buffer = match SourceBuffer::file(path) {\n            Ok(buffer) => buffer,\n            Err(err) => {\n                return TestCaseResult::fail(path, start.elapsed(), format!(\"I/O error: {err}\"));\n            }\n        };\n\n        let entry_cm = match compile_from_source(&buffer, &Default::default()) {\n            Ok(m) => m,\n            Err(e) => {\n                let err_msg = e\n                    .iter()\n                    .map(|e| e.to_string())\n                    .collect::<Vec<_>>()\n                    .join(\"\\n\");\n                return TestCaseResult::fail(\n                    path,\n                    start.elapsed(),\n                    format!(\"compilation error: {err_msg}\"),\n                );\n            }\n        };\n\n        let mut vm = VirtualMachine::default();\n\n        let entry_rm = match vm.load_module(\"\", entry_cm) {\n            Ok(rle) => match rle {\n                haxby_vm::vm::RunloopExit::Ok(m) => m.module,\n                haxby_vm::vm::RunloopExit::Exception(e) => {\n                    let mut frame = Default::default();\n                    let epp = e.value.prettyprint(&mut frame, &mut vm);\n                    return TestCaseResult::fail(path, start.elapsed(), epp);\n                }\n            },\n            Err(err) => return TestCaseResult::fail(path, start.elapsed(), err.prettyprint(None)),\n        };\n\n        match vm.execute_module(&entry_rm) {\n            Ok(rle) => match rle {\n                haxby_vm::vm::RunloopExit::Ok(_) => TestCaseResult::pass(path, start.elapsed()),\n                haxby_vm::vm::RunloopExit::Exception(e) => {\n                    let mut frame = Default::default();\n                    let epp = e.value.prettyprint(&mut frame, &mut vm);\n                    TestCaseResult::fail(path, start.elapsed(), epp)\n                }\n            },\n            Err(err) => {\n                TestCaseResult::fail(path, start.elapsed(), err.prettyprint(Some(entry_rm)))\n            }\n        }\n    };\n\n    let mut outcome = run_once();\n\n    let is_flaky = tags.contains(\"FLAKEY\") || tags.contains(\"FLAKY\");\n    if is_flaky && outcome.result.is_fail() {\n        outcome = run_once();\n    }\n\n    let is_xfail = tags.contains(\"XFAIL\");\n    if is_xfail {\n        match &outcome.result {\n            TestCaseOutcome::Pass => {\n                return TestCaseResult::fail(\n                    path,\n                    start_wall.elapsed(),\n                    \"unexpected pass (XFAIL)\".into(),\n                );\n            }\n            TestCaseOutcome::Fail(reason) => {\n                return TestCaseResult::xfail(path, start_wall.elapsed(), reason.clone());\n            }\n            _ => {\n                panic!(\"test runner should only produce pass/fail\")\n            }\n        }\n    }\n\n    outcome\n}\n\n#[derive(Default)]\nstruct SuiteReport {\n    passes: Vec<TestCaseResult>,\n    fails: Vec<TestCaseResult>,\n    xfails: Vec<TestCaseResult>,\n    duration: Duration,\n}\n\nimpl SuiteReport {\n    fn num_fails(&self) -> usize {\n        self.fails.len()\n    }\n\n    fn num_passes(&self) -> usize {\n        self.passes.len()\n    }\n\n    fn num_xfails(&self) -> usize {\n        self.xfails.len()\n    }\n\n    fn len(&self) -> usize {\n        self.num_fails() + self.num_passes() + self.num_xfails()\n    }\n\n    fn pass(&mut self, result: TestCaseResult) {\n        self.passes.push(result);\n    }\n\n    fn fail(&mut self, result: TestCaseResult) {\n        self.fails.push(result);\n    }\n\n    fn xfail(&mut self, result: TestCaseResult) {\n        self.xfails.push(result);\n    }\n\n    fn sort(&mut self, by: &SortBy) -> &mut Self {\n        match by {\n            SortBy::Name => {\n                self.passes.sort_by(|a, b| a.test.cmp(&b.test));\n                self.fails.sort_by(|a, b| a.test.cmp(&b.test));\n                self.xfails.sort_by(|a, b| a.test.cmp(&b.test));\n            }\n            SortBy::Duration => {\n                self.passes.sort_by(|a, b| a.duration.cmp(&b.duration));\n                self.fails.sort_by(|a, b| a.duration.cmp(&b.duration));\n                self.xfails.sort_by(|a, b| a.duration.cmp(&b.duration));\n            }\n        }\n\n        self\n    }\n}\n\nimpl Display for SuiteReport {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        for pass in &self.passes {\n            writeln!(f, \"{}\", pass)?;\n        }\n        for xfail in &self.xfails {\n            writeln!(f, \"{}\", xfail)?;\n        }\n        for fail in &self.fails {\n            writeln!(f, \"{}\", fail)?;\n        }\n\n        write!(\n            f,\n            \"{} tests total - {} passed, {} failed, {} xfailed - in {}.{:03} seconds\",\n            self.len(),\n            self.num_passes(),\n            self.num_fails(),\n            self.num_xfails(),\n            self.duration.as_secs(),\n            self.duration.subsec_millis(),\n        )\n    }\n}\n\nimpl Termination for SuiteReport {\n    fn report(self) -> ExitCode {\n        if self.num_fails() > 0 {\n            ExitCode::FAILURE\n        } else {\n            ExitCode::SUCCESS\n        }\n    }\n}\n\nfn run_tests_from_pattern(patterns: Paths, args: &Args, skip_regex: &[Regex]) -> SuiteReport {\n    let mut results = SuiteReport::default();\n\n    let start = Instant::now();\n\n    let outcomes = if args.sequential {\n        let mut ret = vec![];\n        for pattern in patterns.flatten() {\n            if should_skip_file_name(&pattern, skip_regex) {\n                continue;\n            }\n\n            let test_name = pattern.file_stem().unwrap().to_str().unwrap();\n            let test_path = pattern.as_os_str().to_str().unwrap();\n            if args.verbose {\n                println!(\"Running {test_name} (at {test_path})\");\n            }\n            let result = run_test_from_pattern(test_path);\n            if args.fail_fast && result.result.is_fail() {\n                ret.push(result);\n                break;\n            } else {\n                ret.push(result);\n            }\n        }\n        ret\n    } else {\n        patterns\n            .flatten()\n            .filter(|p| !should_skip_file_name(p, skip_regex))\n            .par_bridge()\n            .map(|path| {\n                let test_path = path.as_os_str().to_str().unwrap();\n                run_test_from_pattern(test_path)\n            })\n            .collect::<_>()\n    };\n\n    results.duration = start.elapsed();\n\n    for result in outcomes {\n        match &result.result {\n            TestCaseOutcome::Pass => results.pass(result),\n            TestCaseOutcome::Fail(_) => {\n                results.fail(result);\n            }\n            TestCaseOutcome::XFail(_) => {\n                results.xfail(result);\n            }\n        }\n    }\n\n    results\n}\n\nfn main() -> SuiteReport {\n    let args = Args::parse();\n    if args.fail_fast && !args.sequential {\n        println!(\"--fail-fast is only supported in sequential mode; ignoring\");\n    }\n\n    let mut skip_regex = Vec::new();\n    for pattern in &args.skip_pattern {\n        match Regex::new(pattern) {\n            Ok(re) => skip_regex.push(re),\n            Err(e) => {\n                eprintln!(\"invalid --skip-pattern `{pattern}`: {e}\");\n                exit(2);\n            }\n        }\n    }\n\n    let mut results = match glob::glob(&args.path) {\n        Ok(pattern) => run_tests_from_pattern(pattern, &args, &skip_regex),\n        Err(err) => {\n            eprintln!(\"invalid pattern: {err}\");\n            exit(1);\n        }\n    };\n    if results.num_fails() == 0 && !args.verbose {\n        println!(\"All tests passed; --verbose to print full report\");\n        exit(0);\n    }\n\n    results.sort(&args.sort_by);\n\n    println!(\"{}\", results);\n\n    results\n}\n"
  },
  {
    "path": "tests/alloc_builtin_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert alloc(Int) == 0;\n    assert alloc(Float) == 0.0f;\n    assert alloc(Bool) == false;\n    assert alloc(String) == \"\";\n    assert alloc(List) == [];\n}\n"
  },
  {
    "path": "tests/and.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc boolean() {\n    assert (true && true) == true;\n    assert (true && false) == false;\n    assert (false && true) == false;\n    assert (false && false) == false;\n}\n\nfunc integer() {\n    val a =           0b00101110101011110001;\n    val b =           0b00010100001100011010;\n    assert (a & b) == 0b00000100001000010000;\n}\n\nfunc main() {\n    integer();\n    boolean();\n}\n"
  },
  {
    "path": "tests/and_shortcircuit.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = [1,0];\n    assert !(false && (x[0] / x[1] == 4));\n}\n"
  },
  {
    "path": "tests/arg_isa_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin A  {}\n\nstruct S {\n    include A\n}\n\nfunc foo(x: A) {\n    return 42;\n}\n\nstruct T {}\n\nfunc main() {\n    assert foo(alloc(S)) == 42;\n\n    try {\n        foo(alloc(T));\n        assert false;\n    } catch e {\n        assert e.is_UnexpectedType();\n    }\n}\n"
  },
  {
    "path": "tests/arg_typehint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add(x: Int, y: Int) {\n    return x + y;\n}\n\nfunc len_plus_one(x: List) {\n    return add(x.len(), 1);\n}\n\nfunc main() {\n    assert len_plus_one([]) == 1;\n}\n"
  },
  {
    "path": "tests/argc_mismatch_error.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc takes_three(x,y,z) {\n    return x + y - z;\n}\n\nfunc main() {\n    val caught = false;\n\n    try {\n        assert takes_three(1,2,3,4) == 5;\n    } catch e {\n        match e {\n            isa RuntimeError and case MismatchedArgumentCount(n) => {\n                caught = ((n.expected == 3) && (n.actual == 4));\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/aria_version.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nassert ARIA_VERSION != \"\";\nassert ARIA_VERSION.has_prefix(\"0.\"); # this will break for 1.0, let it, we'll fix the test then\n"
  },
  {
    "path": "tests/arity_of_callable.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Callable {\n    operator()(n,m=0) {\n        return n + m + 1;\n    }\n}\n\nfunc main() {\n    val c = alloc(Callable);\n    val a = arity(c);\n\n    assert a.min == 1;\n    assert a.max.is_Bounded();\n    assert a.max.unwrap_Bounded() == 2;\n    assert a.has_receiver == true;\n\n    assert c(1) == 2;\n    assert c(0, 2) == 3;\n}\n"
  },
  {
    "path": "tests/as_user_printable.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func prettyprint() {\n        return \"I'm a Foo\";\n    }\n}\n\nfunc main() {\n    val l = [1,2, alloc(Foo), false, 3.14f];\n\n    assert prettyprint(l) == \"[1, 2, I'm a Foo, false, 3.14]\";\n}\n"
  },
  {
    "path": "tests/assert_id_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval called = false;\n\nfunc assert_test(x,y) {\n    called = true;\n    assert x == y;\n}\n\nfunc main() {\n    assert !called;\n    assert_test(3,3);\n    assert called;\n}\n"
  },
  {
    "path": "tests/bind_call_enum_instance_method.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Foo {\n    case A,\n    case B,\n}\n\nextension Foo {\n    instance func number() {\n        return 42;\n    }\n}\n\nfunc main() {\n    val a = Foo::A;\n    assert a.number() == 42;\n    assert Foo::B.number() == 42;\n}\n"
  },
  {
    "path": "tests/bind_call_enum_type_method.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Foo {}\n\nextension Foo {\n    type func answer() {\n        return 42;\n    }\n}\n\nfunc main() {\n    assert Foo.answer() == 42;\n}\n"
  },
  {
    "path": "tests/bind_of_free_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc x_and_then_some(this,x) {\n    return this.x + x;\n}\n\nstruct Foo {\n    type func new(x) {\n        return alloc(This){\n            .x = x,\n        };\n    }\n}\n\nfunc main() {\n    val f = Foo.new(3);\n\n    # on the instance, do not bind to this\n    f.add = x_and_then_some;\n    assert f.add(f, 4) == 7;\n\n    # on the type, bind to this\n    Foo.and_add = x_and_then_some;\n    assert f.and_add(4) == 7;\n}\n\n"
  },
  {
    "path": "tests/bind_of_func_on_builtin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc x_and_then_some(this,x) {\n    return this + x;\n}\n\nfunc for_int() {\n    Int.bar = x_and_then_some;\n    val n = 3;\n    n.foo = x_and_then_some;\n\n    assert n.foo(4) == 7;\n    assert n.bar(4) == 7;\n}\n\nfunc for_float() {\n    Float.bar = x_and_then_some;\n    val n = 3.0f;\n    n.foo = x_and_then_some;\n\n    assert n.foo(4) == 7.0f;\n    assert n.bar(4) == 7.0f;\n}\n\nfunc for_string() {\n    String.bar = x_and_then_some;\n    val n = \"hello \";\n    n.foo = x_and_then_some;\n\n    assert n.foo(\"world\") == \"hello world\";\n    assert n.bar(\"world\") == \"hello world\";\n}\n\nfunc negate_and(this,x) {\n    return !this && x;\n}\n\nfunc for_bool() {\n    Bool.bar = negate_and;\n    val n = false;\n    n.foo = negate_and;\n\n    assert n.foo(true) == true;\n    assert n.bar(true) == true;\n}\n\nfunc main() {\n    for_int();\n    for_float();\n    for_string();\n    for_bool();\n}\n\n"
  },
  {
    "path": "tests/box_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val b = Box();\n    b.x = 1;\n    b.y = 2;\n    assert b.y == 2;\n    assert b.x == 1;\n}\n"
  },
  {
    "path": "tests/break_in_forloop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4,5];\n    val sum = 0;\n    for item in l {\n        sum = sum + item;\n        if item == 3 {\n            break;\n        }\n    }\n\n    assert sum == 6;\n}\n"
  },
  {
    "path": "tests/build_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Answer {\n    func answer() {\n        return 42;\n    }\n}\n\nfunc main() {\n    assert hasattr(Answer, \"answer\");\n}\n"
  },
  {
    "path": "tests/builtin_isa_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Double {\n    func double(x) {\n        return x * 2;\n    }\n}\n\nextension Int {\n    include Double\n}\n\nfunc main() {\n    assert 3 isa Double;\n}\n"
  },
  {
    "path": "tests/builtin_maybe_enum.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc double(x) {\n    return x + x;\n}\n\nfunc main() {\n    val s = Maybe::Some(123);\n    val n = Maybe::None;\n\n    assert(s.is_Some());\n    assert(n.is_None());\n    assert(s.unwrap_Some() == 123);\n\n    val double_s = s.apply(double).apply(double);\n    val double_n = n.apply(double).apply(double);\n\n    assert(double_s.is_Some());\n    assert(double_n.is_None());\n\n    assert(double_s.unwrap_Some() == 492);\n}\n"
  },
  {
    "path": "tests/builtin_type_func_takes_This.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Int {\n    type func from_string(x: String) {\n        return This.parse(x)!;\n    }\n}\n\nfunc main() {\n    val n = Int.from_string(\"123\");\n    assert n == 123;\n}\n"
  },
  {
    "path": "tests/builtin_type_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 3;\n    val y = typeof(x);\n    assert x isa Int;\n    assert y == Int;\n    val z = typeof(y);\n    assert z == Type;\n    assert z isa Type; # Type is the root of the hierarchy so no matter how deep you go...\n    assert typeof(typeof(typeof(typeof(typeof(typeof(3)))))) == Type;\n}\n"
  },
  {
    "path": "tests/builtins_list_attributes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val i = 3;\n    i.foo = \"three\";\n\n    val i_attributes = listattrs(i);\n    assert i_attributes.contains(\"foo\");\n    assert i_attributes.contains(\"hash\");\n    assert i_attributes.contains(\"parse\"); # should type methods be included?\n    assert i_attributes.len() >= 3;\n\n    val f = 3.14f;\n    f.text = \"pi\";\n\n    val f_attributes = listattrs(f);\n    assert f_attributes.contains(\"text\");\n    assert f_attributes.contains(\"hash\");\n    assert f_attributes.len() >= 2;\n\n    val b = false;\n    b.truthy = false;\n\n    val b_attributes = listattrs(b);\n    assert b_attributes.contains(\"truthy\");\n    assert b_attributes.contains(\"hash\");\n    assert b_attributes.len() >= 2;\n\n    val s = \"hello\";\n    s.french = \"bonjour\";\n\n    val s_attributes = listattrs(s);\n    assert s_attributes.contains(\"french\");\n    assert s_attributes.contains(\"hash\");\n    assert s_attributes.len() >= 2;\n\n    val l = [1,2,3];\n    l.max = 3;\n    l.sum = 6;\n\n    val l_attributes = listattrs(l);\n    assert l_attributes.contains(\"max\");\n    assert l_attributes.contains(\"sum\");\n    assert l_attributes.contains(\"len\");\n    assert l_attributes.len() >= 3;\n}\n"
  },
  {
    "path": "tests/bw_ops.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc min(x: Float, y: Float) {\n    if x < y {\n        return x;\n    } else {\n        return y;\n    }\n}\n\nfunc max(x: Float, y: Float) {\n    if x > y {\n        return x;\n    } else {\n        return y;\n    }\n}\n\nstruct FuzzyNumber {\n    type func new(x: Float) {\n        return alloc(This){\n            .x = x%1,\n        };\n    }\n\n    operator &(other) {\n        if other isa FuzzyNumber {\n            return FuzzyNumber.new(min(this.x, other.x));\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator |(other) {\n        if other isa FuzzyNumber {\n            return FuzzyNumber.new(max(this.x, other.x));\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator u-() {\n        return FuzzyNumber.new(1 - this.x);\n    }\n\n    operator ^(other) {\n        if other isa FuzzyNumber {\n            return (this | other) & -(this & other);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator ==(other) {\n        if other isa FuzzyNumber {\n            return this.x == other.x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    val a = FuzzyNumber.new(0.3f);\n    val b = FuzzyNumber.new(0.4f);\n\n    assert (a&b) == a;\n    assert (a|b) == b;\n\n    assert (a^b) == b;\n}\n"
  },
  {
    "path": "tests/call_op_call.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct HasOpCall {\n    operator ()() {\n        return 123;\n    }\n}\n\nstruct CanBeCalled {\n    type func new() {\n        return alloc(This);\n    }\n\n    operator ()() {\n        return alloc(HasOpCall)();\n    }\n}\n\nfunc main() {\n    # should this really be supported?\n    assert (CanBeCalled.new())() == 123;\n}\n"
  },
  {
    "path": "tests/call_struct_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func write(x) {\n        this.x = x;\n    }\n\n    func read() {\n        return this.x;\n    }\n}\n\nfunc main() {\n    val f = alloc(Foo);\n    f.write(123);\n    assert f.read() == 123;\n    f.write(456);\n    assert f.read() == 456;\n}\n"
  },
  {
    "path": "tests/chained_try_unwrap.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok, err from aria.core.result;\n\nval n = ok(ok(ok(3)));\n\nassert n??? == 3;\nassert n??! == 3;\nassert n!?? == 3;\nassert n!!! == 3;\n\nval m = ok(3);\n\nval m = m ? == 3 ? 4 : 5;\nassert m == 4;\n"
  },
  {
    "path": "tests/closure_range_list.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\nimport Range from aria.range.range;\n\nfunc main() {\n    val closures = [];\n    val how_many = Range.from(0).through(100);\n    \n    for i in how_many {\n        closures.append(|x| => x + i);\n    }\n\n    val x = 0;\n    for closure in closures {\n        assert closure(3) == 3 + x;\n        x += 1;\n    }\n}\n"
  },
  {
    "path": "tests/closure_with_body.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc greater_than_N(N) {\n    return |x| => {\n        if x > N {\n            return true;\n        } else {\n            return false;\n        }\n    };\n}\n\nfunc main() {\n    assert greater_than_N(5)(3) == false;\n    assert greater_than_N(6)(8) == true;\n    assert greater_than_N(5)(6) == true;\n    assert greater_than_N(3)(1) == false; \n}\n"
  },
  {
    "path": "tests/cmp_utils.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport min,max,min_max from aria.ordering.utils;\nimport min_with_comparator,max_with_comparator,min_max_with_comparator from aria.ordering.utils;\nimport CompareResult from aria.ordering.compare;\n\nfunc main() {\n    val list = [1,2,3,4,5,6,7,8,9,10];\n\n    assert min(list) == 1;\n    assert max(list) == 10;\n    val mM = min_max(list);\n    assert mM.min == 1;\n    assert mM.max == 10;\n\n    list = [\"a\", \"abc\", \"hello world\", \"this is a very long string\"];\n    val cmp = |x,y| => {\n        if x.len() == y.len() {\n            return CompareResult::eq;\n        } elsif x.len() < y.len() {\n            return CompareResult::lt;\n        } else {\n            return CompareResult::gt;\n        }\n    };\n\n    assert min_with_comparator(list, cmp) == \"a\";\n    assert max_with_comparator(list, cmp) == \"this is a very long string\";\n    mM = min_max_with_comparator(list, cmp);\n    assert mM.min == \"a\";\n    assert mM.max == \"this is a very long string\";\n}\n"
  },
  {
    "path": "tests/complex_hash.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Complex from aria.numerics.complex;\n\nfunc main() {\n    val c1 = Complex.new(3,5);\n    val c2 = Complex.new(4,3);\n    val c3 = Complex.new(1,1);\n\n    assert c1.hash() != c2.hash();\n    assert c1.hash() != c3.hash();\n    assert c2.hash() != c3.hash();\n\n    assert c1.hash() == c1.hash();\n    assert c2.hash() == c2.hash();\n    assert c3.hash() == c3.hash();\n\n    val c4 = Complex.new(1,1);\n\n    assert c4.hash() == c3.hash();\n    assert c3 == c4;\n}\n"
  },
  {
    "path": "tests/complex_numbers.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Complex from aria.numerics.complex;\n\nfunc complex(i,j) {\n    return Complex.new(i) + j * Complex.i;\n}\n\nfunc main() {\n    val one = complex(1,0);\n    val some_num = complex(3,2);\n\n    assert one == 1;\n    assert one == 1.0f;\n\n    assert some_num != 3;\n    assert some_num != 2;\n    assert some_num != 3.0f;\n    assert some_num != 2.0f;\n\n    assert (some_num + one) == complex(4,2);\n\n    assert one + complex(0,1) == complex(1,1);\n    assert 1 + complex(2,2) == some_num;\n\n    assert (some_num - one) == complex(2,2);\n    assert (some_num - complex(0,2)) == 3;\n\n    assert 1 - complex(1,2) - complex(0,1) == complex(0,-3);\n\n    assert complex(3,2) * complex(4,-1) == complex(14,5);\n    assert 2 * complex(0,1) == complex(0,2);\n    assert 2 * complex(1,0) == 2;\n\n    assert some_num.conj() == complex(3,-2);\n    assert one.conj() == one;\n\n    assert complex(3,4).reciprocal() == complex(0.12f, -0.16f);\n\n    val quot = complex(2,3) / complex(1,-2);\n\n    assert (quot.real + 0.8f).abs() <= 0.0001f;\n    assert (quot.imag - 1.4f).abs() <= 0.0001f;\n}\n"
  },
  {
    "path": "tests/complex_of_self.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Complex from aria.numerics.complex;\n\nfunc main() {\n    val error = false;\n    try {\n        val c1 = Complex.new(\"hello\", 5);\n    } catch e {\n        error = true;\n        assert e isa RuntimeError;\n        assert e.is_UnexpectedType();\n    }\n\n    assert error;\n}\n"
  },
  {
    "path": "tests/complex_reverse_minus.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Complex from aria.numerics.complex;\n\nassert (3 - Complex.new(3,4)).imag == -4;\n"
  },
  {
    "path": "tests/continue_in_forloop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4,5];\n    val sum = 0;\n    for item in l {\n        sum = sum + item;\n        continue;\n        assert false;\n    }\n\n    assert sum == 15;\n}\n"
  },
  {
    "path": "tests/cross_func_exception.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc throws(x: Int) {\n    throw x + 1;\n}\n\nfunc call_throw() {\n    println(throws(5));\n}\n\nfunc handle_it() {\n    val handled = false;\n    try {\n        call_throw();\n    } catch e {\n        handled = true;\n        assert e == 6;\n    }\n    \n    return handled;\n}\n\nfunc main() {\n    assert handle_it() == true;\n}\n"
  },
  {
    "path": "tests/cross_module_mixin_import.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport MeFirst from same_root.part1.file3;\nimport Foo from same_root.part1.file1;\n\nfunc main() {\n    val f = Foo.new();\n    val m = MeFirst.new();\n    \n    assert f.answer() == 165;\n    assert m.answer() == 363;\n}"
  },
  {
    "path": "tests/cross_module_var.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport * from exported_var.source;\n\nfunc main() {\n    assert foo == 123;\n    assert fetch_foo() == 123;\n    assert exported_var.source.foo == 123;\n    assert exported_var.source.fetch_foo() == 123;\n\n    change_foo(111);\n    assert foo == 123; # TODO: should it be 111?\n    assert fetch_foo() == 111;\n    assert exported_var.source.foo == 111;\n    assert exported_var.source.fetch_foo() == 111;\n\n    exported_var.source.change_foo(222);\n    assert foo == 123; # TODO: should it be 222?\n    assert fetch_foo() == 222;\n    assert exported_var.source.foo == 222;\n    assert exported_var.source.fetch_foo() == 222;\n}\n"
  },
  {
    "path": "tests/cross_module_var_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: XFAIL\n\nimport * from exported_var.source;\n\nfunc main() {\n    foo = 456;\n    assert foo == 456;\n    assert fetch_foo() == 456; # expected to fail here\n    assert exported_var.source.foo == 456;\n    assert exported_var.source.fetch_foo() == 456;\n}\n"
  },
  {
    "path": "tests/custom_is_unwrap.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum E {\n    case A(Int),\n    case B,\n    case C(String)\n\n    func is_A() {\n        return 12;\n    }\n\n    func unwrap_C() {\n        return \"hello\";\n    }\n}\n\nfunc main() {\n    val ea = E::A(5);\n    val eb = E::B;\n    val ec = E::C(\"world\");\n\n    assert ea.is_A() == 12;\n    assert eb.is_A() == 12;\n    assert ec.is_A() == 12;\n\n    assert ea.unwrap_C() == \"hello\";\n    assert ea.unwrap_A() == 5;\n\n    assert eb.unwrap_C() == \"hello\";\n    \n    assert ec.unwrap_C() == \"hello\";\n}\n"
  },
  {
    "path": "tests/custom_to_json_value.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.json.writer;\nimport JsonValue from aria.json.value;\nimport Map from aria.structures.map;\n\nstruct CustomJson {\n    type func new(x,y) {\n        return alloc(This) {\n            .x = x,\n            .y = y,\n        };\n    }\n\n    func to_json_value() {\n        return Result::Ok(JsonValue::Object(Map.new() {\n            [\"x\"] = JsonValue.new_with_value(this.x)?,\n            [\"y\"] = JsonValue.new_with_value(this.y)?,\n        }));\n    }\n}\n\nfunc main() {\n    val map = Map.new();\n    map[\"hello\"] = CustomJson.new(3,4);\n    map[\"hi\"] = false;\n\n    val json_map = JsonValue.new_with_value(map)!;\n\n    assert json_map isa JsonValue;\n\n    val unwrap_map = json_map.unwrap_Object();\n    assert unwrap_map isa Map;\n\n    assert unwrap_map[\"hello\"].is_Object();\n    val custom_object = unwrap_map[\"hello\"].flatten();\n    assert custom_object isa Map;\n    assert custom_object[\"x\"] == 3.0f;\n    assert custom_object[\"y\"] == 4.0f;\n\n    assert unwrap_map[\"hi\"].is_Boolean();\n    assert unwrap_map[\"hi\"].flatten() == false;\n}\n"
  },
  {
    "path": "tests/custom_try_unwrap_protocol.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok,err from aria.core.result;\n\nstruct Number {\n    type func new(x) = alloc(This) {.x};\n\n    func _op_try_view() {\n        if this.x == 5 {\n            return ok(this.x);\n        } else {\n            return err(\"not five\");\n        }\n    }\n}\n\nfunc main() {\n    val five = Number.new(5);\n    val six = Number.new(6);\n\n    assert five? == 5;\n    assert five! == 5;\n\n    assert six?.is_Err();\n    assert six?.unwrap_Err() == \"not five\";\n}\n"
  },
  {
    "path": "tests/decimal.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Decimal from aria.numerics.decimal;\n\nfunc main() {\n    assert Decimal.parse(\"3.14\")! + Decimal.parse(\"3.14\")! == Decimal.new(6.28f);\n    assert 3 + Decimal.parse(\"5\")! == Decimal.new(8);\n    assert 3.1f + Decimal.parse(\"2.5\")! == Decimal.new(5.6f);\n    assert Decimal.parse(\"5\")! - Decimal.parse(\"3.1\")! == Decimal.parse(\"1.9\")!;\n    assert 4 - Decimal.parse(\"3.5\")! == Decimal.new(0.5f);\n\n    assert Decimal.parse(\"3.14\")! * 2 == Decimal.new(6.28f);\n    assert 2 * Decimal.parse(\"3.14\")! == Decimal.new(6.28f);\n    assert Decimal.parse(\"12\")! / Decimal.new(3) == Decimal.new(4);\n    assert 12 / Decimal.parse(\"3\")! == Decimal.new(4);\n\n    assert Decimal.parse(\"3.14\")! > Decimal.parse(\"2.0\")!;\n    assert Decimal.parse(\"5.123\")! < Decimal.parse(\"6.28\")!;\n\n    assert Decimal.parse(\"5\")! != Decimal.parse(\"6\")!;\n\n    assert Decimal.new(5) >= Decimal.new(4);\n    assert Decimal.new(5) >= Decimal.parse(\"5.00000\")!;\n\n    assert Decimal.parse(\"5.0\")! <= Decimal.new(5);\n    assert Decimal.parse(\"5.0\")! <= Decimal.new(5.001);\n\n    assert Decimal.parse(\"foo\").is_Err();\n    assert Decimal.parse(\"3.14.15\").is_Err();\n    assert Decimal.parse(\"3.14e2\").is_Err(); # TODO: support scientific notation\n}\n"
  },
  {
    "path": "tests/decimal_hash.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Decimal from aria.numerics.decimal;\n\nfunc main() {\n    val d1 = Decimal.parse(\"123.456\")!;\n    val d2 = Decimal.parse(\"123.457\")!;\n    val d3 = Decimal.parse(\"321.456\")!;\n\n    assert d1.hash() != d2.hash();\n    assert d1.hash() != d3.hash();\n    assert d2.hash() != d3.hash();\n\n    assert d1.hash() == d1.hash();\n    assert d2.hash() == d2.hash();\n    assert d3.hash() == d3.hash();\n\n    val d4 = Decimal.parse(\"321.456\")!;\n\n    assert d4.hash() == d3.hash();\n    assert d3 == d4;\n}\n"
  },
  {
    "path": "tests/decimal_prettyprint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Decimal from aria.numerics.decimal;\n\nfunc main() {\n    val f1 = Decimal.parse(\"3.14159265359\")!;\n\n    assert \"{0}\".format(f1) == \"3.14159265359\";\n\n    assert \"{0:.2}\".format(f1) == \"3.14\";\n    assert \"{0:.3}\".format(f1) == \"3.142\";\n    assert \"{0:.4}\".format(f1) == \"3.1416\";\n}\n"
  },
  {
    "path": "tests/deep_nested_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct A {\n    struct B {\n        struct C {\n            struct D {\n                func foo() {\n                    return 42;\n                }\n            }\n\n            type func subtract(x,y) {\n                return x - y;\n            }\n        }\n        type func getD() {\n            return alloc(A.B.C.D);\n        }\n\n        instance func bar() {\n            return 123;\n        }\n    }\n\n    type func whoami() {\n        return \"A\";\n    }\n\n    instance func multiply(x,y) {\n        return x * y;\n    }\n}\n\nfunc main() {\n    assert hasattr(A, \"B\");\n    assert hasattr(A.B, \"C\");\n    assert hasattr(A.B.C, \"D\");\n\n    assert hasattr(A, \"whoami\");\n    assert hasattr(A.B, \"getD\");\n\n    assert A.whoami() == \"A\";\n    assert alloc(A).multiply(3,4) == 12;\n\n    assert A.B.getD().foo() == 42;\n    assert alloc(A.B).bar() == 123;\n\n    assert A.B.C.subtract(7,4) == 3;\n\n    assert alloc(A.B.C.D).foo() == 42;\n}\n"
  },
  {
    "path": "tests/default_arg_is_immutable.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add_to_list(n,l=[]) {\n    l.append(n);\n    return l;\n}\n\nfunc main() {\n    val l1 = add_to_list(3);\n    assert l1 == [3];\n\n    val l2 = add_to_list(5);\n    assert l1 == [3];\n    assert l2 == [5];\n\n    l2 = add_to_list(7,l2);\n    assert l2 == [5,7];\n    assert l1 == [3];\n}\n"
  },
  {
    "path": "tests/dir_entries.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\nimport Instant from aria.date.instant;\nimport Path from aria.io.path;\n\nfunc is_this_test(path) {\n    return path.get_filename()! == \"dir_entries.aria\";\n}\n\nfunc main() {\n    val path = getenv(\"ARIA_TEST_DIR\").unwrap_Some();\n    val path = Path.new(path).new_canonical().unwrap_Ok();\n\n    val entries = path.entries();\n    entries = entries.where(is_this_test).to_list();\n\n    assert entries.len() == 1;\n    assert entries[0] isa Path;\n    assert entries[0].is_file();\n    assert entries[0].exists();\n    assert entries[0].get_extension()! == \"aria\";\n\n    val creation = entries[0].created()!;\n    val modified = entries[0].modified()!;\n    val accessed = entries[0].accessed()!;\n\n    assert creation.year >= 2025;\n    assert modified.year >= 2025;\n    assert accessed.year >= 2025;\n\n    assert accessed.utc_timestamp_ms >= modified.utc_timestamp_ms;\n    assert modified.utc_timestamp_ms >= creation.utc_timestamp_ms;\n\n    if creation.year == 2025 {\n        assert creation.month >= 7;\n\n        if creation.month == 7 {\n            assert creation.day >= 4;\n        } else {\n            assert creation.day >= 1;\n        }\n    } else {\n        assert creation.month >= 1;\n        assert creation.day >= 1;\n    }\n}\n"
  },
  {
    "path": "tests/div_by_zero_error.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val caught = false;\n\n    try {\n        println(3 / 0);\n    } catch e {\n        match e {\n            isa RuntimeError and case DivisionByZero => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/dot_write_of_local.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Pair {\n    type func new(x,y) = alloc(This){.x, .y};\n\n    func swap() {\n        return Pair.new(this.y, this.x);\n    }\n}\n\nfunc main() {\n    val p = Pair.new(3,4);\n    assert p.x == 3;\n    assert p.y == 4;\n\n    val q = p.swap();\n    assert q.x == 4;\n    assert q.y == 3;\n}\n"
  },
  {
    "path": "tests/double_import_from.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Pair from example.pair.Pair;\nimport Pair from example.pair.Pair;\nimport Pair from example.pair.Pair;\n\nextension Pair {\n    func min() {\n        if this.x > this.y {\n            return this.y;\n        } else {\n            return this.x;\n        }\n    }\n}\n\nfunc main() {\n    val p = Pair.new(1,2);\n    val q = Pair.new(3,4);\n\n    assert p.max() == 2;\n    assert q.max() == 4;\n\n    assert p.min() == 1;\n    assert q.min() == 3;\n}\n"
  },
  {
    "path": "tests/double_module_import.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport example.pair.Pair;\nimport example.pair.Pair;\nimport example.pair.Pair;\nimport Pair from example.pair.Pair;\n\nfunc main() {\n    val p = Pair.new(1,2);\n    assert p.x == 1;\n    assert p.y == 2;\n}\n"
  },
  {
    "path": "tests/empty_expr_stmt.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo() {\n    ;;;;;;\n}\n\nfunc bar() {\n    if 1 == 1 {\n        return true;\n    };;;;\n\n    return false;;;;;;\n}\n\nfunc main() {\n    ;\n    foo();\n    assert bar();;;;;\n}\n"
  },
  {
    "path": "tests/empty_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo() {}\n\nfunc main() {\n    foo();\n}\n"
  },
  {
    "path": "tests/enum_case_as_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin A {\n    func answer() = 42;\n}\n\nstruct S {\n    include A\n}\n\nenum E {\n    case HasAnswer(A),\n    case DefaultAnswer(Int),\n\n    func answer() {\n        match this {\n            case HasAnswer(a) => {\n                return a.answer();\n            },\n            case DefaultAnswer(n) => {\n                return n;\n            }\n        }\n    }\n}\n\nfunc main() {\n    val e1 = E::HasAnswer(alloc(S));\n    assert e1.answer() == 42;\n\n    val e2 = E::DefaultAnswer(7);\n    assert e2.answer() == 7;\n}\n"
  },
  {
    "path": "tests/enum_case_check_no_payload.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Foo {\n    case A,\n    case B,\n    case C,\n    case D,\n    case E,\n}\n\nstruct WhichCase {\n    type func new() {\n        return alloc(This){\n            .is_a = false,\n            .is_b = false,\n            .is_c = false,\n            .is_d = false,\n        };\n    }\n}\n\nfunc check_cases(x: Foo) {\n    val wc: WhichCase = WhichCase.new();\n\n    match x {\n        case A => { wc.is_a = true; },\n        case B => { wc.is_b = true; },\n        case C => { wc.is_c = true; },\n        case D => { wc.is_d = true; },\n    }\n\n    return wc;\n}\n\nfunc main() {\n    val a = Foo::A;\n    val b = Foo::B;\n    val c = Foo::C;\n    val d = Foo::D;\n    val e = Foo::E;\n\n    val check: WhichCase = check_cases(a);\n    assert check.is_a;\n    assert !check.is_b;\n    assert !check.is_c;\n    assert !check.is_d;\n\n    val check: WhichCase = check_cases(b);\n    assert !check.is_a;\n    assert check.is_b;\n    assert !check.is_c;\n    assert !check.is_d;\n\n    val check: WhichCase = check_cases(c);\n    assert !check.is_a;\n    assert !check.is_b;\n    assert check.is_c;\n    assert !check.is_d;\n\n    val check: WhichCase = check_cases(d);\n    assert !check.is_a;\n    assert !check.is_b;\n    assert !check.is_c;\n    assert check.is_d;\n\n    val check: WhichCase = check_cases(e);\n    assert !check.is_a;\n    assert !check.is_b;\n    assert !check.is_c;\n    assert !check.is_d;\n}\n"
  },
  {
    "path": "tests/enum_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n: Int) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return rhs == this.n;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nenum Something {\n    case WithPayload(Any),\n    case WithoutPayload\n}\n\nfunc main() {\n    val s1 = Something::WithoutPayload;\n\n    assert s1 == Something::WithoutPayload;\n\n    val s2 = Something::WithPayload(3);\n    val s3 = Something::WithPayload(Integer.new(3));\n    val s4 = Something::WithPayload(4);\n\n    assert s2 == s3;\n    assert s3 == s2;\n\n    assert s3 != s4;\n    assert s2 != s4;\n\n    assert s4 != s3;\n    assert s4 != s2;\n    \n    assert s1 != s2;\n    assert s2 != s1;\n\n    assert s3 != s1;\n    assert s1 != s3;\n\n    assert s1 != s4;\n    assert s4 != s1;\n}\n"
  },
  {
    "path": "tests/enum_extend_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Enum {\n    case A,\n    case B,\n}\n\nmixin LogicalOps {\n    func some_op() {\n        return 123;\n    }\n}\n\nextension Enum {\n    include LogicalOps\n}\n\nextension LogicalOps {\n    func some_other_op() {\n        return 321;\n    }\n}\n\nfunc main() {\n    val e = Enum::A;\n    assert e.some_op() == 123;\n    assert e.some_other_op() == 321;\n}\n"
  },
  {
    "path": "tests/enum_in_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Parent {\n    enum Child {\n        case A,\n        case B(Int)\n    }\n}\n\nextension Parent.Child {\n    func get_magic_value() {\n        return 123;\n    }\n}\n\nextension Parent {\n    type func get_child_A() {\n        return Parent.Child::A;\n    }\n\n    type func get_child_B(x: Int) {\n        return Parent.Child::B(x);\n    }\n}\n\nfunc main() {\n    # cannot test match yet\n    val a = Parent.get_child_A();\n    assert a.get_magic_value() == 123;\n    val b = Parent.get_child_B(456);\n    assert b.get_magic_value() == 123;\n}\n"
  },
  {
    "path": "tests/enum_isa_mixn.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin M {\n    func foo(x) {\n        return x + 1;\n    }\n}\n\nmixin MM {\n    func bar(x) {\n        return this.foo(x) + 1;\n    }\n\n    include M\n}\n\nenum IncludeM {\n    case A, case B\n}\n\nextension IncludeM {\n    include M\n}\n\nenum IncludeMM {\n    case C, case D\n}\n\nextension IncludeMM {\n    include MM\n}\n\nfunc main() {\n    val m = IncludeM::A;\n    val mm = IncludeMM::D;\n\n    assert m isa M;\n    assert mm isa MM;\n    assert mm isa M;\n\n    assert !(m isa MM);\n\n    assert MM isa M;\n    assert !(M isa MM);\n\n    assert IncludeM isa M;\n    assert !(IncludeM isa MM);\n    assert IncludeMM isa MM;\n    assert IncludeMM isa M;\n}\n"
  },
  {
    "path": "tests/enum_list_attributes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum E1 {\n    case A, case B\n}\n\nenum E2 {\n    case A, case B(Int)\n}\n\nmixin PlusSeven {\n    func f7(x) {\n        return x + 7;\n    }\n}\n\nextension E1 {\n    include PlusSeven\n\n    func f1(x) {\n        return x + 1;\n    }\n    func f2(x) {\n        return x * 2;\n    }\n}\n\nextension E2 {\n    func f3(x) {\n        return x + 3;\n    }\n    func f4(x) {\n        return x + 4;\n    }\n}\n\nfunc main() {\n    val e1 = E1::A;\n    val e2 = E2::A;\n\n    val attribs_e1 = listattrs(e1);\n    val attribs_e2 = listattrs(e2);\n\n    assert attribs_e1.contains(\"f1\");\n    assert attribs_e1.contains(\"f2\");\n    assert attribs_e1.contains(\"f7\");\n    assert attribs_e1.contains(\"is_A\");\n    assert attribs_e1.contains(\"is_B\");\n    assert attribs_e1.len() == 5;\n\n    assert attribs_e2.contains(\"f3\");\n    assert attribs_e2.contains(\"f4\");\n    assert attribs_e2.contains(\"is_A\");\n    assert attribs_e2.contains(\"is_B\");\n    assert attribs_e2.contains(\"unwrap_B\");\n    assert attribs_e2.len() == 5;\n}\n"
  },
  {
    "path": "tests/enum_match_case_first_wins.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = Maybe::Some(123);\n    val a = false;\n    val b = false;\n\n    match x {\n        case Some(x: Int) => { a = true; },\n        case Some(x) => {assert(false);},\n    } else {\n        assert(false);\n    }\n\n    match x {\n        case Some(x) => {b = true;},\n        case Some(x: Int) => {assert(false);},\n    } else {\n        assert(false);\n    }\n\n    assert a;\n    assert b;\n}"
  },
  {
    "path": "tests/enum_match_case_typehint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = Maybe::Some(123);\n    val n = 0;\n\n    match x {\n        case Some(x: String) => {assert(false);},\n        case Some(x: List) => {assert(false);},\n        case None => {assert(false);},\n        case Some(x: Int) => { n = x; },\n        case Some(x) => {assert(false);},\n    } else {\n        assert(false);\n    }\n\n    assert n == 123;\n}"
  },
  {
    "path": "tests/enum_op_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Something {\n    case WithPayload(Any),\n    case WithoutPayload\n}\n\nextension Something {\n    # only doing this for test purposes, it's actually a terrible\n    # definition of an equality comparison\n    operator ==(rhs) {\n        match rhs {\n            isa Something => { return true; }\n        } else {\n            return false;\n        }\n    }\n}\n\nfunc main() {\n    assert Something::WithPayload(3) == Something::WithoutPayload;\n\n    assert 3 != Something::WithoutPayload;\n    assert 3 != Something::WithPayload(3);\n}\n"
  },
  {
    "path": "tests/enum_prettyprint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Parity {\n    case Even(Int),\n    case Odd(Int),\n}\n\nextension Parity {\n    type func new(n: Int) {\n        if n % 2 == 0 {\n            return Parity::Even(n);\n        } else {\n            return Parity::Odd(n);\n        }\n    }\n\n    instance func prettyprint() {\n        match this {\n            case Even(x) => {\n                return \"{0} is an even number\".format(x);\n            },\n            case Odd(x) => {\n                return \"{0} is an odd number\".format(x);\n            }\n        }\n    }\n}\n\nfunc main() {\n    val six = Parity.new(6);\n    val eleven = Parity.new(11);\n\n    val six_fmt = \"{0}\".format(six);\n    val eleven_fmt = \"{0}\".format(eleven);\n\n    assert six_fmt == \"6 is an even number\";\n    assert eleven_fmt == \"11 is an odd number\";\n}\n"
  },
  {
    "path": "tests/enum_with_struct_case.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Options {\n    struct LotsOfThem {\n        type func new(opt1, opt2, opt3) {\n            return alloc(This) {\n                .opt1 = opt1,\n                .opt2 = opt2,\n                .opt3 = opt3,\n            };\n        }\n    }\n\n    struct FewerOfThem {\n        type func new(opt1) {\n            return alloc(This) {\n                .opt1 = opt1,\n            };\n        }\n    }\n\n    case Lots(Options.LotsOfThem)\n    case Fewer(Options.FewerOfThem)\n\n    func option1() {\n        match this {\n            case Lots(x) => { return x.opt1; },\n            case Fewer(x) => { return x.opt1; },\n        }\n    }\n\n    func option2() {\n        match this {\n            case Lots(x) => { return x.opt2; },\n            case Fewer => { return 42; },\n        }\n    }\n\n    func option3() {\n        match this {\n            case Lots(x) => { return x.opt3; },\n            case Fewer => { return 24; },\n        }\n    }\n}\n\nfunc main() {\n    val ol = Options::Lots(Options.LotsOfThem.new(1,2,3));\n    val of = Options::Fewer(Options.FewerOfThem.new(4));\n\n    assert ol.option1() == 1;\n    assert ol.option2() == 2;\n    assert ol.option3() == 3;\n\n    assert of.option1() == 4;\n    assert of.option2() == 42;\n    assert of.option3() == 24;\n}\n"
  },
  {
    "path": "tests/enum_without_payload.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum E {\n    case NoPayload,\n    case Payload(Any)\n}\n\nfunc get_maybe_something(x: E) {\n    match x {\n        # NoPayload case should not extract payload, but it tries\n        # it can't match (and if it does it's a bug in the compiler or in the VM)\n        # but it also should just fail to match and move on to the next case\n        case NoPayload(x) => { assert false; },\n        case Payload(x) => { return Maybe::Some(x); }\n        case NoPayload => { return Maybe::None; }\n    }\n\n    assert false;\n}\n\nfunc main() {\n    assert get_maybe_something(E::NoPayload) == Maybe::None;\n    assert get_maybe_something(E::Payload(42))! == 42;\n}\n"
  },
  {
    "path": "tests/except_in_op_is_caught.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct InvalidArgument {}\n\nstruct Divider {\n    operator /(rhs) {\n        if rhs == 0 {\n            throw alloc(InvalidArgument);\n        } else {\n            return 1;\n        }\n    }\n}\n\nfunc main() {\n    val caught = false;\n\n    try {\n        alloc(Divider) / 0;\n    } catch e {\n        caught = e isa InvalidArgument;\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/exception_backtrace.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc bar() {\n    return foo();\n}\n\nfunc foo() {\n    throw 1;\n}\n\nfunc main() {\n    try {\n        bar();\n    } catch e {\n        assert hasattr(e, \"backtrace\");\n        assert e.backtrace.len() >= 2;\n        assert e.backtrace[0][0].contains(\"exception_backtrace.aria\");\n        assert e.backtrace[0][1] == 6;\n        assert e.backtrace[1][0].contains(\"exception_backtrace.aria\");\n        assert e.backtrace[1][1] == 2;\n    }\n}\n"
  },
  {
    "path": "tests/extend_imported.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Base from extensible.ext;\nimport Base from extensible.base;\n\nfunc main() {\n    val b = Base.new(2,3);\n    b.one_right();\n    assert b.x == 2;\n    assert b.y == 4;\n}\n"
  },
  {
    "path": "tests/extend_included_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin FunStuff {\n    func have_fun() {\n        return 123;\n    }\n}\n\nstruct WantsFun {\n    include FunStuff\n}\n\nextension FunStuff {\n    func have_more_fun() {\n        return 456;\n    }\n}\n\nfunc main() {\n    val wf = alloc(WantsFun);\n    assert wf.have_fun() == 123;\n    assert wf.have_more_fun() == 456;\n}\n"
  },
  {
    "path": "tests/extend_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func increment(x) {\n        return x + 1;\n    }\n}\n\nextension Foo {\n    func double(x) {\n        return x + x;\n    }\n}\n\nextension Foo {\n    func zero() {\n        return 0;\n    }\n\n    func one() {\n        return 1;\n    }\n\n    func two() {\n        return 2;\n    }\n}\n\nfunc main() {\n    val foo = alloc(Foo);\n    assert foo.increment(5) == 6;\n    assert foo.double(12) == 24;\n    assert foo.zero() == 0;\n    assert foo.one() == 1;\n    assert foo.two() == 2;\n}\n"
  },
  {
    "path": "tests/extension_nested_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct A {\n    struct B {\n        struct C {\n            struct D {\n            }\n        }\n    }\n}\n\nextension A.B.C.D {\n    type func new() {\n        return alloc(This);\n    }\n\n    instance func answer() {\n        return 42;\n    }\n}\n\nextension A.B.C {\n    instance func answer() {\n        return 42;\n    }\n}\n\nextension A.B {\n    type func whoami() {\n        return \"A.B\";\n    }\n}\n\nextension A {\n    instance func getD() {\n        return A.B.C.D.new();\n    }\n}\n\nval nested_struct = A.B.C;\n\nextension nested_struct {\n    type func question() {\n        return 24;\n    }\n}\n\nextension A {\n    struct OneMore {\n        type func new(x) {\n            return alloc(This){\n                .x = x\n            };\n        }\n\n        instance func increment() {\n            this.x = this.x + 1;\n            return this;\n        }\n    }\n}\n\nextension A.OneMore {\n    instance func get() {\n        return this.x;\n    }\n}\n\nfunc main() {\n    assert hasattr(A.B.C.D, \"new\");\n    assert hasattr(A.B, \"whoami\");\n    assert hasattr(A.B.C, \"question\");\n    assert hasattr(A, \"OneMore\");\n\n    assert alloc(A).getD().answer() == 42;\n    assert A.B.C.D.new().answer() == 42;\n\n    assert alloc(A.B.C).answer() == 42;\n    assert A.B.C.question() == 24;\n\n    assert A.B.whoami() == \"A.B\";\n\n    val aom = A.OneMore.new(12);\n    assert aom.get() == 12;\n    aom.increment().increment().increment();\n    assert aom.get() == 15;\n}\n"
  },
  {
    "path": "tests/extension_on_list.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension List {\n    func head() {\n        return this[0];\n    }\n}\n\nfunc main() {\n    val list = [1,2,3,4,5,6];\n    assert list.head() == 1;\n}\n"
  },
  {
    "path": "tests/extension_type_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension List {\n    type func empty() {\n        return [];\n    }\n}\n\nfunc main() {\n    assert hasattr(List, \"empty\");\n\n    val l = List.empty();\n    assert l.len() == 0;\n}\n"
  },
  {
    "path": "tests/file_io.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport File from aria.io.file;\nimport guard from aria.utils.guard;\n\nfunc main() {\n    val path = getenv(\"ARIA_TEST_DIR\").unwrap_Some();\n    path = path + \"/file_io.txt\";\n\n    val msg = \"First line of text.\\nSecond line of text.\\nThird line of text.\";\n\n    guard(File.open(path, File.OpenMode.new().write().truncate())).do(|file| => {\n        file.write(msg);\n    });\n\n    guard(File.open(path, File.OpenMode.new().read())).do(|file| => {\n        assert file.get_position() == 0;\n        val l1 = file.readln();\n        assert file.get_position() == 20;\n        assert l1 == \"First line of text.\";\n        val s = file.read_all();\n        assert s == \"Second line of text.\\nThird line of text.\";\n\n        file.set_position(1);\n        s = file.read(2);\n        assert file.get_position() == 3;\n        assert s == \"ir\";\n        s = file.readln();\n        assert file.get_position() == 20;\n        s == \"st line of text.\";\n\n        file.seek(File.SeekMode::Start(1));\n        s = file.read(2);\n        assert file.get_position() == 3;\n        assert s == \"ir\";\n\n        file.seek(File.SeekMode::Current(2));\n        s = file.read(2);\n        assert file.get_position() == 7;\n        assert s == \" l\";\n\n        file.seek(File.SeekMode::Current(-3));\n        s = file.read(3);\n        assert file.get_position() == 7;\n        assert s == \"t l\";\n\n        file.seek(File.SeekMode::End(-4));\n        s = file.read(4);\n        assert s == \"ext.\";\n    });\n}\n"
  },
  {
    "path": "tests/file_io.txt",
    "content": "First line of text.\nSecond line of text.\nThird line of text."
  },
  {
    "path": "tests/file_lines_iter.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport File from aria.io.file;\nimport Enumerate from aria.iterator.enumerate;\nimport guard from aria.utils.guard;\n\nfunc main() {\n    val path = getenv(\"ARIA_TEST_DIR\").unwrap_Some();\n    path = path + \"/file_lines_iter.txt\";\n\n    val msg = \"First line of text.\\nSecond line of text.\\n\\nThird line of text.\\nFourth line of text.\";\n\n    guard(File.open(path, File.OpenMode.new().write().truncate())).do(|file| => {\n        file.write(msg);\n    });\n\n    val lines = [\n        \"First line of text.\",\n        \"Second line of text.\",\n        \"\",\n        \"Third line of text.\",\n        \"Fourth line of text.\"\n    ];\n\n    guard(File.open(path, File.OpenMode.new().read())).do(|file| => {\n        for idx_line in Enumerate.new(file.lines()) {\n            val line = idx_line.value;\n            val i = idx_line.index;\n            assert line == lines[i];\n        }\n    });\n}\n"
  },
  {
    "path": "tests/file_lines_iter.txt",
    "content": "First line of text.\nSecond line of text.\n\nThird line of text.\nFourth line of text."
  },
  {
    "path": "tests/flatten_results.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok, err from aria.core.result;\nimport aria.range.int_extension;\n\nfunc give_out_a_result(x) {\n    if x % 2 == 0 {\n        return ok(x);\n    } else {\n        return err(\"odd number: {0}\".format(x));\n    }\n}\n\nfunc main() {\n    val l = 1.to(4)\n        .map(give_out_a_result)\n        .flatten_results();\n\n    assert l == err(\"odd number: 1\");\n\n    val l = 2.to(4)\n        .map(|x| => x * 2)    \n        .map(give_out_a_result)\n        .flatten_results();\n\n    assert l.is_Ok();\n    assert l.unwrap_Ok() == [4,6];\n}\n"
  },
  {
    "path": "tests/float_atan.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.numerics.float.trig;\n\nfunc within_tolerance(expected: Float, got: Float, rel_tol: Float = 1.0e-9, abs_tol: Float = 1.0e-15) {\n    val diff = (got - expected).abs();\n    val tol = expected.abs() * rel_tol;\n    if tol < abs_tol {\n        tol = abs_tol;\n    }\n    return diff <= tol;\n}\n\nassert within_tolerance(0.0, 0.0.arctan());\nassert within_tolerance(Float.π / 4, 1.0.arctan());\nassert within_tolerance(-Float.π / 4, (-1.0).arctan());\n\nassert within_tolerance(0.4636476090008061, 0.5.arctan());\nassert within_tolerance(-0.4636476090008061, (-0.5).arctan());\n\nassert within_tolerance(1.0e-10, (1.0e-10).arctan());\nassert within_tolerance(-1.0e-10, (-1.0e-10).arctan());\n\nassert within_tolerance(Float.π / 2 - 1.0e-10, (1.0e10).arctan(), 1.0e-9);\nassert within_tolerance(-Float.π / 2 + 1.0e-10, (-1.0e10).arctan(), 1.0e-9);\n\nassert within_tolerance(0.7853981133974458, 0.9999999.arctan());\n\nassert within_tolerance(0.19739555984988078, 0.2.arctan());\nassert within_tolerance(-1.3258176636680326, (-4.0).arctan());\n\nassert within_tolerance(0.4636476090008061, (0.5f).arctan());\nassert within_tolerance(-0.7853981633974483, (-1.0f).arctan());\n"
  },
  {
    "path": "tests/float_exp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.numerics.float.exp;\n\nfunc within_tolerance(expected: Float, got: Float, rel_tol: Float = 1.0e-9, abs_tol: Float = 1.0e-15) {\n    val diff = (got - expected).abs();\n    val tol = expected.abs() * rel_tol;\n    if tol < abs_tol {\n        tol = abs_tol;\n    }\n    return diff <= tol;\n}\n\nassert within_tolerance(1.0, 0.0.exp());\nassert within_tolerance(2.718281828459045, 1.0.exp());\nassert within_tolerance(0.36787944117144233, (-1.0).exp());\nassert within_tolerance(4.851651954097903e8, 20.0.exp());\nassert within_tolerance(1.9287498479639178e-22, (-50.0).exp());\n"
  },
  {
    "path": "tests/float_ln.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.numerics.float.exp;\n\nfunc within_tolerance(expected: Float, got: Float, rel_tol: Float = 1.0e-9, abs_tol: Float = 1.0e-15) {\n    val diff = (got - expected).abs();\n    val tol = expected.abs() * rel_tol;\n    if tol < abs_tol {\n        tol = abs_tol;\n    }\n    return diff <= tol;\n}\n\nassert within_tolerance(0.0, 1.0.ln());\nassert within_tolerance(0.6931471805599453, 2.0.ln());\nassert within_tolerance(69.07755278982138, (1.0e30).ln(), 1.0e-12);\nassert within_tolerance(-115.12925464970229, (1.0e-50).ln(), 1.0e-12);\n"
  },
  {
    "path": "tests/float_log_exp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.numerics.float.exp;\n\nfunc within_tolerance(expected: Float, got: Float, rel_tol: Float = 1.0e-9, abs_tol: Float = 1.0e-15) {\n    val diff = (got - expected).abs();\n    val tol = expected.abs() * rel_tol;\n    if tol < abs_tol {\n        tol = abs_tol;\n    }\n    return diff <= tol;\n}\n\nfunc roundtrip_le(x: Float) {\n    return x.ln().exp();\n}\n\nfunc roundtrip_el(x: Float) {\n    return x.exp().ln();\n}\n\nfunc check_roundtrip_el(x: Float) {\n    val y = x.exp();\n    val z = y.ln();\n    return within_tolerance(x, z);\n}\n\nfunc check_roundtrip_le(x: Float) {\n    val y = x.ln();\n    val z = y.exp();\n    return within_tolerance(x, z);\n}\n\nfunc main() {\n    assert check_roundtrip_el(2.0f);\n    assert check_roundtrip_le(2.0f);\n\n    assert check_roundtrip_el(3.4635f);\n    assert check_roundtrip_le(3.4635f);\n\n    val had_error = false;\n\n    try {\n        (-1.1f).ln();\n    } catch e {\n        had_error = e isa Float.DomainError;\n    }\n\n    assert had_error;\n}\n"
  },
  {
    "path": "tests/float_parse_scientific.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nval x1 = 1.0E3;\nval y1 = Float.parse(\"1.0E3\")!;\nassert x1 == y1;\nassert y1 == 1000.0f;\n\nval x2 = 1.0e3;\nval y2 = Float.parse(\"1.0e3\")!;\nassert x2 == y2;\nassert y2 == 1000.0f;\n\nval x3 = 1.0e-3;\nval y3 = Float.parse(\"1.0e-3\")!;\nassert x3 == y3;\nassert y3 == 0.001f;\n\nval x4 = 1.0e+3;\nval y4 = Float.parse(\"1.0e+3\")!;\nassert x4 == y4;\nassert y4 == 1000.0f;\n\nval x5 = 2.0e2;\nval y5 = Float.parse(\"2.0e2\")!;\nassert x5 == y5;\nassert y5 == 200.0f;\n\nval x6 = 0.0e10;\nval y6 = Float.parse(\"0.0e10\")!;\nassert x6 == y6;\nassert y6 == 0.0f;\n\nval x7 = -1.5e2;\nval y7 = Float.parse(\"-1.5e2\")!;\nassert x7 == y7;\nassert y7 == -150.0f;\n"
  },
  {
    "path": "tests/float_pow.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.numerics.float.exp;\n\nfunc rough_approx_eq(x: Float, y: Float) {\n    return (x-y).abs() <= 0.00001f;\n}\n\nfunc main() {\n    assert((-2.0f).pow(2) == 4.0f);\n    assert(3.0f.pow(2.0f) == 9.0f);\n\n    assert(rough_approx_eq(3.7f.pow(2.12f), 16.01724f));\n    assert(rough_approx_eq(1245.0f.pow(0.73f), 181.74967f));\n\n    val caught_err = false;\n    try {\n        (-1.1f).pow(3.5f);\n    } catch e {\n        caught_err =  e isa Float.DomainError;\n    }\n\n    assert caught_err;\n}\n"
  },
  {
    "path": "tests/float_pretyprint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val f1 = 3.14159265359;\n\n    assert \"{0:.2}\".format(f1) == \"3.14\";\n    assert \"{0:.3}\".format(f1) == \"3.142\";\n    assert \"{0:.4}\".format(f1) == \"3.1416\";\n\n    val f2 = 123456789.987654321;\n    assert \"{0:.E}\".format(f2) == \"1.2345678998765433e8\";\n\n    assert \"{0}\".format(f1) == \"3.14159265359\";\n    assert \"{0}\".format(f2) == \"123456789.98765433\";\n}\n"
  },
  {
    "path": "tests/float_sqrt.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert (4.0f.sqrt() - 2.0f).abs() <= 0.0001f;\n    assert (9.0f.sqrt() - 3.0f).abs() <= 0.0001f;\n}\n"
  },
  {
    "path": "tests/flt_attrib.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Float {\n    func double() {\n        return this * 2;\n    }\n}\n\nfunc main() {\n    val f = 1.234f;\n    f.zero = 0.0f;\n\n    assert f.zero == 0.0f;\n    assert f.double() == 2.468f;\n}\n"
  },
  {
    "path": "tests/for_else.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l1 = [1,2,3,4];\n\n    val l2 = [];\n\n    val count_l1 = 0;\n    for x in l1 {\n        count_l1 += 1;\n    } else {\n        assert false; # this should not execute\n    }\n\n    assert count_l1 == 4;\n\n    val count_l2 = 0;\n    val else_hit = false;\n    for x in l2 {\n        count_l2 += 1;\n    } else {\n        else_hit = true;\n    }\n\n    assert count_l2 == 0;\n    assert else_hit == true;\n}\n"
  },
  {
    "path": "tests/for_loop_test.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct IteratorValue {\n    type func end() = Maybe::None;\n\n    type func more(v) = Maybe::Some(v);\n}\n\nstruct GenValues {\n    type func new(f,t) {\n        return alloc(This){\n            .from = f,\n            .to = t,\n        };\n    }\n\n    struct GenValuesIterator {\n        type func new(gv) {\n            return alloc(This) {\n                .from = gv.from,\n                .to = gv.to,\n                .current = gv.from,\n            };\n        }\n\n        func next() {\n            if this.current == this.to {\n                return IteratorValue.end();\n            } else {\n                val ret = IteratorValue.more(this.current);\n                this.current = this.current + 1;\n                return ret;\n            }\n        }\n    }\n\n    func iterator() {\n        return GenValues.GenValuesIterator.new(this);\n    }\n}\n\nfunc main() {\n    val gv = GenValues.new(3,10);\n    val sum = 0;\n    for n in gv {\n        sum = sum + n;\n    }\n    assert sum == 42;\n}"
  },
  {
    "path": "tests/format_of_nested_brace.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nassert \"{{{0}}}\".format(\"hello world\") == \"{hello world}\";\n"
  },
  {
    "path": "tests/format_with_opt_arg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct PrettyPrintable {\n    type func new() {\n        return alloc(This);\n    }\n\n    func prettyprint(style=\"xyz\") {\n        return \"PrettyPrintable({0})\".format(style);\n    }\n}\n\nfunc main() {\n    val pp = PrettyPrintable.new();\n\n    val s1 = \"{0}\".format(pp);\n    val s2 = \"{0:abc}\".format(pp);\n    val s3 = \"{0:}\".format(pp);\n\n    assert s1 == \"PrettyPrintable(xyz)\";\n    assert s2 == \"PrettyPrintable(abc)\";\n    assert s3 == \"PrettyPrintable()\";\n}\n"
  },
  {
    "path": "tests/fp_arith.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add() {\n    val f1 = 1.25f;\n    val f2 = 0.5f;\n\n    assert f1 + f2 == 1.75f;\n}\n\nfunc sub() {\n    val f1 = 1.25f;\n    val f2 = 0.25f;\n\n    assert f1 - f2 == 1.0f;\n}\n\nfunc mul() {\n    val f1 = 1.25f;\n    val f2 = 2.0f;\n\n    assert f1 * f2 == 2.5f;\n}\n\nfunc div() {\n    val f1 = 2.5f;\n    val f2 = 1.25f;\n\n    assert f1 / f2 == 2.0f;\n}\n\nfunc main() {\n    add();\n    sub();\n    mul();\n    div();\n}\n\n"
  },
  {
    "path": "tests/fp_cmp_greater.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc is_greater(x,y) {\n    return x > y;\n}\n\nfunc main() {\n    assert is_greater(3.14f, 0);\n    assert is_greater(4, 1.1f);\n    assert is_greater(1.1f, 0.1f);\n\n    assert !is_greater(3.14f, 5.0f);\n    assert !is_greater(1, 1.1f);\n    assert !is_greater(2.0f, 4);\n}\n"
  },
  {
    "path": "tests/fp_cmp_gt_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc greater_or_equal(x,y) {\n    return x >= y;\n}\n\nfunc main() {\n    assert greater_or_equal(1.0f, 1.0f);\n    assert greater_or_equal(1.0f, 0);\n    assert greater_or_equal(1, 0.1f);\n\n    assert !greater_or_equal(1.1f, 3.14f);\n    assert !greater_or_equal(2, 3.14f);\n    assert !greater_or_equal(3.14f, 5);\n}\n"
  },
  {
    "path": "tests/fp_cmp_lt_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc lesser_or_equal(x,y) {\n    return x <= y;\n}\n\nfunc main() {\n    assert lesser_or_equal(1.0f, 1.0f);\n    assert !lesser_or_equal(1.0f, 0);\n    assert !lesser_or_equal(1, 0.1f);\n\n    assert lesser_or_equal(1.1f, 3.14f);\n    assert lesser_or_equal(2, 3.14f);\n    assert lesser_or_equal(3.14f, 5);\n}\n"
  },
  {
    "path": "tests/fp_cmp_smaller.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc is_smaller(x,y) {\n    return x < y;\n}\n\nfunc main() {\n    assert !is_smaller(3.14f, 0);\n    assert !is_smaller(4, 1.1f);\n    assert !is_smaller(1.1f, 0.1f);\n\n    assert is_smaller(3.14f, 5.0f);\n    assert is_smaller(1, 1.1f);\n    assert is_smaller(2.0f, 4);\n}\n"
  },
  {
    "path": "tests/fp_consts.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert hasattr(Float, \"inf\");\n    assert hasattr(Float, \"nan\");\n    assert hasattr(Float, \"epsilon\");\n\n    assert Float.inf > 1.0f;\n    assert 1.0f > -Float.inf;\n\n    assert Float.inf > -Float.inf;\n    assert -Float.inf < Float.inf;\n    \n    assert Float.nan != Float.nan;\n}"
  },
  {
    "path": "tests/fp_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 1.25f;\n    val y = 0.25f;\n    val z = 1;\n\n    assert x == x;\n    assert y == y;\n    assert (x - y) == z;\n}\n"
  },
  {
    "path": "tests/fp_ext_notation.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = 3.5e2f;\n    val b = 31.4e-1f;\n\n    assert a == 350;\n    assert b == 3.14f;\n}\n"
  },
  {
    "path": "tests/fp_int_arith.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add() {\n    val x = 1;\n    val y = 1.25f;\n\n    assert x + y == 2.25f;\n    assert y + x == 2.25f;\n}\n\nfunc sub() {\n    val x = 1;\n    val y = 1.25f;\n\n    assert x - y == -0.25f;\n    assert y - x == 0.25f;\n}\n\nfunc mul() {\n    val x = 2;\n    val y = 3.25f;\n\n    assert x * y == 6.5f;\n    assert y * x == 6.5f;\n}\n\nfunc div() {\n    val x = 2;\n    val y = 4.0f;\n\n    assert x / y == 0.5f;\n    assert y / x == 2.0f;\n}\n\nfunc main() {\n    add();\n    sub();\n    mul();\n    div();\n}\n"
  },
  {
    "path": "tests/fp_no_suffix.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nfunc basic_parsing() {\n    val x = 1.25;\n    val y = 1.25f;\n    assert x == y;\n}\n\nfunc arithmetic_add() {\n    val a = 3.14;\n    val b = 2.86f;\n    assert a + b == 6.0f;\n\n    val c = 1.5;\n    val d = 0.5;\n    assert c + d == 2.0f;\n}\n\nfunc arithmetic_sub() {\n    val a = 3.14;\n    val b = 1.14f;\n    assert a - b == 2.0f;\n\n    val c = 5.5;\n    val d = 2.5f;\n    assert c - d == 3.0f;\n}\n\nfunc arithmetic_mul() {\n    val a = 2.5;\n    val b = 2.0f;\n    assert a * b == 5.0f;\n\n    val c = 1.25;\n    val d = 4.0f;\n    assert c * d == 5.0f;\n}\n\nfunc arithmetic_div() {\n    val a = 10.0;\n    val b = 2.5f;\n    assert a / b == 4.0f;\n\n    val c = 7.5;\n    val d = 2.5f;\n    assert c / d == 3.0f;\n}\n\nfunc comparison_greater() {\n    assert 3.14 > 3.0f;\n    assert 4.2 > 1.1f;\n    assert 1.5 > 0.5f;\n\n    assert !(2.0 > 3.14f);\n    assert !(1.5 > 2.0f);\n}\n\nfunc comparison_lesser() {\n    assert 2.0 < 3.14f;\n    assert 1.1 < 4.2f;\n    assert 0.5 < 1.5f;\n\n    assert !(3.14 < 2.0f);\n    assert !(4.2 < 1.1f);\n}\n\nfunc comparison_greater_equal() {\n    assert 3.14 >= 3.14f;\n    assert 3.14 >= 3.0f;\n    assert 4.2 >= 1.1f;\n\n    assert !(2.0 >= 3.14f);\n    assert !(1.1 >= 4.2f);\n}\n\nfunc comparison_lesser_equal() {\n    assert 3.14 <= 3.14f;\n    assert 3.0 <= 3.14f;\n    assert 1.1 <= 4.2f;\n\n    assert !(3.14 <= 2.0f);\n    assert !(4.2 <= 1.1f);\n}\n\nfunc scientific_notation() {\n    val a = 3.14e2;\n    val b = 31.4e-1f;\n\n    assert a == 314.0f;\n    assert b == 3.14f;\n\n    val c = 1.5e1;\n    assert c == 15.0f;\n}\n\nfunc negative_numbers() {\n    val x = -3.14;\n    val y = -3.14f;\n    assert x == y;\n\n    val a = -2.5;\n    val b = 5.5f;\n    assert a + b == 3.0f;\n\n    val c = -1.25;\n    val d = -0.75f;\n    assert c - d == -0.5f;\n}\n\nfunc mixed_with_integers() {\n    val result1 = 1.5 + 2;\n    assert result1 == 3.5f;\n\n    val result2 = 3 - 1.5;\n    assert result2 == 1.5f;\n\n    val result3 = 2.5 * 3;\n    assert result3 == 7.5f;\n\n    val result4 = 7.5 / 3;\n    assert result4 == 2.5f;\n}\n\nfunc mixed_suffix_operations() {\n    val a = 1.25;\n    val b = 0.75f;\n    val c = 2.0;\n\n    assert a + b == c;\n    assert (a * 2.0f) == 2.5f;\n    assert (b / 0.25) == 3.0f;\n}\n\nfunc main() {\n    basic_parsing();\n    arithmetic_add();\n    arithmetic_sub();\n    arithmetic_mul();\n    arithmetic_div();\n    comparison_greater();\n    comparison_lesser();\n    comparison_greater_equal();\n    comparison_lesser_equal();\n    scientific_notation();\n    negative_numbers();\n    mixed_with_integers();\n    mixed_suffix_operations();\n}\n"
  },
  {
    "path": "tests/from_import_two_things.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport One from example.two.things;\nimport Two from example.two.things;\n\nfunc main() {\n    val t1 = One.new(4);\n    assert t1.double() == 10;\n\n    val t2 = Two.new(7);\n    assert t2.half() == 3;\n}\n"
  },
  {
    "path": "tests/func_arg_type_mismatch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add(x: Int, y: Int) {\n    return x + y;\n}\n\nfunc main() {\n    val caught = false;\n\n    try {\n        add(1, \"2\");\n        assert false;\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/func_as_arg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc double(x) {\n    return x + x;\n}\n\nfunc perform_op(f,n) {\n    return f(n);\n}\n\nfunc main() {\n    assert perform_op(double,4) == 8;\n}\n"
  },
  {
    "path": "tests/func_has_multiple_optionals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc test(a,b,c=2,d=5,e=7) {\n    return a + b * c + d * e;\n}\n\nfunc main() {\n    assert test(1,2) == 40;\n    assert test(1,2,3) == 42;\n    assert test(1,2,3,4) == 35;\n    assert test(1,2,3,4,5) == 27;\n}\n"
  },
  {
    "path": "tests/func_has_only_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add_numbers(...) {\n    val ret = 0;\n    for n in varargs {\n        ret += n;\n    }\n    return ret;\n}\n\nfunc main() {\n    assert add_numbers(1,2,3,4) == 10;\n    assert add_numbers(5) == 5;\n    assert add_numbers(5,6) == 11;\n    assert add_numbers() == 0;\n}\n\n\n"
  },
  {
    "path": "tests/func_has_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add_numbers(n, ...) {\n    val ret = n;\n    for n in varargs {\n        ret += n;\n    }\n    return ret;\n}\n\nfunc main() {\n    assert add_numbers(1,2,3,4) == 10;\n    assert add_numbers(5) == 5;\n    assert add_numbers(5,6) == 11;\n}\n\n"
  },
  {
    "path": "tests/func_multiple_fixed_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add_numbers(x,y,z, ...) {\n    val ret = x+y+z;\n    for n in varargs {\n        ret += n;\n    }\n    return ret;\n}\n\nfunc main() {\n    assert add_numbers(1,2,3,4) == 10;\n    assert add_numbers(5,3,2) == 10;\n    assert add_numbers(1,2,3,4,5,6,7,8,9,10) == 55;\n}\n\n"
  },
  {
    "path": "tests/func_only_takes_opt.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc test(x=1,y=2) {\n    return x * y + 1;\n}\n\nfunc main() {\n    assert test() == 3;\n    assert test(2) == 5;\n    assert test(2, 3) == 7;\n}\n"
  },
  {
    "path": "tests/func_order_of_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc compare(l,...) {\n    assert l == varargs;\n}\n\nfunc main() {\n    compare([3],3);\n    compare([3,4],3,4);\n    compare([3,4,5,6],3,4,5,6);\n    compare([]);\n}\n"
  },
  {
    "path": "tests/func_returns_int.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo() {\n    return 1 + 2;\n}\n\nfunc main() {\n    val n = foo();\n    assert n == 3;\n}\n"
  },
  {
    "path": "tests/func_returns_unit.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc no_return_value(x,y) {\n    x + y;\n}\n\nfunc sometimes_returns(x,y) {\n    if (x > y) {\n        return x + y;\n    }\n}\n\nfunc main() {\n    val x = no_return_value(1, 2);\n    assert x isa Unit;\n    assert x.is_unit();\n\n    x = sometimes_returns(3, 2);\n    assert x isa Int;\n    assert x == 5;\n\n    x = sometimes_returns(1, 2);\n    assert x isa Unit;\n    assert x.is_unit();\n}\n"
  },
  {
    "path": "tests/func_takes_args.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc subtract(x,y) {\n    return x-y;\n}\n\nfunc main() {\n    val n = subtract(5,2);\n    assert n == 3;\n}\n"
  },
  {
    "path": "tests/func_type_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc f1(x) {\n    return x + 1;\n}\n\nfunc f2(x,y) {\n    return x + y + 1;\n}\n\nfunc f3(x, ...) {\n    return x;\n}\n\nfunc f4(x) {\n    return x - 1;\n}\n\nfunc f5(y,x) {\n    return y - x;\n}\n\nfunc f6(...) {\n    return false;\n}\n\nfunc f7(x, ...) {\n    return 1;\n}\n\nfunc main() {\n    assert f1 isa typeof(f4);\n    assert !(f1 isa typeof(f2));\n\n    assert f4 isa typeof(f1);\n    assert !(f4 isa typeof(f6));\n\n    assert f2 isa typeof(f5);\n    assert f3 isa typeof(f7);\n    \n    assert !(f6 isa typeof(f3));\n    assert !(f7 isa typeof(f6));\n\n    assert f5 isa typeof(f2);\n    assert !(f6 isa typeof(f1));\n\n    assert !(f6 isa typeof(f7));\n}\n"
  },
  {
    "path": "tests/func_union_type_mismatch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc id(x: Int|String) {\n    x;\n}\n\nfunc main() {\n    val caught = false;\n\n    try {\n        id(Box());\n        assert false;\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/func_with_opt_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc test(a,b=1,...) {\n    val ret = a + b;\n    for arg in varargs {\n        ret += arg;\n    }\n    return ret;\n}\n\nfunc main() {\n    assert test(5) == 6;\n    assert test(5, 2) == 7;\n    assert test(5, 2, 3) == 10;\n    assert test(5, 2, 3, 4) == 14;\n}\n"
  },
  {
    "path": "tests/func_with_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x,y) {\n    struct Pair {\n        type func new(x,y) {\n            return alloc(This) {\n                .x = x,\n                .y = y,\n            };\n        }\n\n        func add() {\n            return this.x + this.y;\n        }\n\n        func max() {\n            if (this.x > this.y) {\n                return this.x;\n            } else {\n                return this.y;\n            }\n        }\n    }\n\n    return Pair.new(x,y);\n}\n\nfunc main() {\n    val p = foo(3,4);\n    assert(p.add() == 7);\n    assert(p.max() == 4);\n}\n"
  },
  {
    "path": "tests/function_arity.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc f1(x,y,z) {}\n\nfunc f2(x,y,z=1) {}\n\nfunc f3(x, ...) {}\n\nfunc f4(...) {}\n\nfunc f5(x,y=1,...) {}\n\nfunc f6(x=1,y=2) {}\n\nfunc f7(x=1,y=2,...) {}\n\nstruct S {\n    func f1(x,y=1) {}\n    func f2(x=0,y=1,...) {}\n\n    type func f3() {}\n    func f4() {}\n}\n\nfunc check_arity(f, min_wanted, should_accept, should_not_accept, is_va) {\n    val f_arity = arity(f);\n    assert f_arity.min == min_wanted;\n    assert f_arity.can_call_with_argc(should_accept);\n    assert !f_arity.can_call_with_argc(should_not_accept);\n    assert f_arity.is_Varargs() == is_va;\n}\n\nfunc main() {\n    check_arity(f1,\n        3, # min argc wanted\n        3, # acceptable argc\n        4, # should not accept\n        false);\n    assert !arity(f1).has_receiver;\n\n    check_arity(f2,\n        2, # min argc wanted\n        3, # acceptable argc\n        4, # should not accept\n        false);\n    check_arity(f2,\n        2, # min argc wanted\n        2, # acceptable argc\n        0, # should not accept\n        false);\n    assert !arity(f2).has_receiver;\n\n    check_arity(f3,\n        1, # min argc wanted\n        2, # acceptable argc\n        0, # should not accept\n        true);\n    check_arity(f3,\n        1, # min argc wanted\n        4, # acceptable argc\n        0, # should not accept\n        true);\n    assert !arity(f3).has_receiver;\n\n    check_arity(f4,\n        0, # min argc wanted\n        2, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(f4,\n        0, # min argc wanted\n        0, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(f4,\n        0, # min argc wanted\n        5, # acceptable argc\n        -1, # should not accept\n        true);\n    assert !arity(f4).has_receiver;\n    assert arity(f4).can_call_with_argc(250);\n\n    check_arity(f5,\n        1, # min argc wanted\n        2, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(f5,\n        1, # min argc wanted\n        4, # acceptable argc\n        -1, # should not accept\n        true);\n    assert !arity(f5).has_receiver;\n\n    check_arity(f6,\n        0, # min argc wanted\n        0, # acceptable argc\n        3, # should not accept\n        false);\n    check_arity(f6,\n        0, # min argc wanted\n        1, # acceptable argc\n        3, # should not accept\n        false);\n    check_arity(f6,\n        0, # min argc wanted\n        2, # acceptable argc\n        4, # should not accept\n        false);\n    assert !arity(f6).has_receiver;\n\n    check_arity(f7,\n        0, # min argc wanted\n        0, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(f7,\n        0, # min argc wanted\n        1, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(f7,\n        0, # min argc wanted\n        2, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(f7,\n        0, # min argc wanted\n        4, # acceptable argc\n        -1, # should not accept\n        true);\n    assert !arity(f7).has_receiver;\n\n    val s = alloc(S);\n\n    check_arity(s.f1,\n        1, # min argc wanted\n        1, # acceptable argc\n        3, # should not accept\n        false);\n    check_arity(s.f1,\n        1, # min argc wanted\n        2, # acceptable argc\n        3, # should not accept\n        false);\n    assert arity(s.f1).has_receiver;\n\n    check_arity(s.f2,\n        0, # min argc wanted\n        1, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(s.f2,\n        0, # min argc wanted\n        2, # acceptable argc\n        -1, # should not accept\n        true);\n    check_arity(s.f2,\n        0, # min argc wanted\n        3, # acceptable argc\n        -1, # should not accept\n        true);\n    assert arity(s.f2).has_receiver;\n\n    check_arity(S.f3,\n        0, # min argc wanted\n        0, # acceptable argc\n        1, # should not accept\n        false);\n    assert arity(S.f3).has_receiver;\n\n    check_arity(s.f4,\n        0, # min argc wanted\n        0, # acceptable argc\n        1, # should not accept\n        false);\n    assert arity(s.f4).has_receiver;\n}\n"
  },
  {
    "path": "tests/function_list_attributes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x,y) {\n    return x + y + foo.n;\n}\n\nfoo.n = 123;\n\nfunc main() {\n    val l = |x,y| => x + y;\n    l.n = 456;\n\n    val foo_attrs = listattrs(foo);\n    assert foo_attrs.contains(\"n\");\n    assert foo_attrs.len() >= 1;\n\n    val l_attrs = listattrs(l);\n    assert l_attrs.contains(\"n\");\n    assert l_attrs.len() >= 1;\n}\n"
  },
  {
    "path": "tests/getenv.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val ARIA_LIB_DIR = getenv(\"ARIA_LIB_DIR\");\n    assert ARIA_LIB_DIR.is_Some();\n\n    assert ARIA_LIB_DIR.unwrap_Some().len() > 0;\n    assert ARIA_LIB_DIR.unwrap_Some()[0] == \"/\";\n\n    val NO_SUCH_ENV_VAR = getenv(\"THERESHOULDBENOSUCHVARIABLEANYWHERE\");\n    assert NO_SUCH_ENV_VAR.is_None();\n}\n"
  },
  {
    "path": "tests/guard_on_return.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct Guard {\n    type val COUNTER = 0;\n\n    instance func guard_exit() {\n        Guard.COUNTER = Guard.COUNTER + 1;\n    }\n}\n\nfunc add(x,y) {\n    return guard(alloc(Guard)).do(|g| => {\n        return x + y;\n    })?;\n}\n\nfunc main() {\n    assert Guard.COUNTER == 0;\n    val n = add(3,4);\n    assert n == 7;\n    assert Guard.COUNTER == 1;\n}\n"
  },
  {
    "path": "tests/guards_exit_on_throw.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct Guard {\n    type val COUNTER = 0;\n\n    func guard_exit() {\n        Guard.COUNTER = Guard.COUNTER + 1;\n    }\n}\n\nfunc ths() {\n    guard(alloc(Guard)).do(|g| => {\n        throw 1;\n    });\n}\n\nfunc catches() {\n    val caught = false;\n    try {\n        ths();\n    } catch e {\n        caught = (e == 1);\n        assert Guard.COUNTER == 1;\n    }\n\n    return caught;\n}\n\nfunc main() {\n    assert catches() == true;\n    assert Guard.COUNTER == 1;\n}\n"
  },
  {
    "path": "tests/has_attr.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func blah() {\n        return 0;\n    }\n\n    func answer() {\n        return 42;\n    }\n}\n\nextension Foo {\n    func question() {\n        return \"?\";\n    }\n}\n\nextension List {\n    instance func head() {\n        return this[0];\n    }\n}\n\nfunc main() {\n    assert hasattr(Foo, \"blah\");\n    assert !hasattr(Foo, \"answer\");\n    assert !hasattr(Foo, \"question\");\n\n    val foo = alloc(Foo);\n    assert hasattr(foo, \"answer\");\n    assert hasattr(foo, \"question\");\n\n    val s = \"hello\";\n    assert hasattr(s, \"len\");\n\n    val l = [1,2,3,4];\n    assert hasattr(l, \"len\");\n    assert hasattr(l, \"head\");\n    assert !hasattr(List, \"len\");\n    assert !hasattr(List, \"head\");\n}\n"
  },
  {
    "path": "tests/hash_builtins.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc string() {\n    val s1 = \"hello\";\n    assert s1.hash() != 0;\n    val s2 = \"world\";\n    assert s2.hash() != s1.hash();\n}\n\nfunc int() {\n    assert 123.hash() == 123;\n    assert 5555.hash() == 5555;\n}\n\nfunc bool() {\n    assert true.hash() != false.hash();\n}\n\nfunc float() {\n    val f1 = 3.14f;\n    val f2 = 1.112f;\n\n    assert f1.hash() != 0;\n    assert f2.hash() != f1.hash();\n    assert f2.hash() != 0;\n}\n\nfunc main() {\n    string();\n    int();\n    float();\n    bool();\n}\n\n"
  },
  {
    "path": "tests/hash_instant.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Instant from aria.date.instant;\n\nfunc main() {\n    val i1 = Instant.new_with_utc_timestamp(1234567890);\n    val i2 = Instant.new_with_utc_timestamp(0);\n    val i3 = Instant.new_with_utc_timestamp(1234567890).with_timezone_offset(1); # nowhere real should have a 1 minute TZ offset\n\n    assert i1 != i2;\n    assert i1 != i3;\n    assert i3 != i2;\n\n    assert i1.hash() == i1.hash();\n    assert i1.hash() != i2.hash();\n    assert i1.hash() != i3.hash();\n    assert i2.hash() != i3.hash();\n}\n"
  },
  {
    "path": "tests/hash_maybe.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func hash() {\n        return 42;\n    }\n}\n\nfunc main() {\n    val a = Maybe::None;\n    assert a.hash() == 0;\n\n    a = Maybe::Some(alloc(Foo));\n    assert a.hash() == 42;\n}\n"
  },
  {
    "path": "tests/hex_escapes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"\\x41bc\\x20 \\x42\";\n    assert s == \"Abc  B\";\n\n    val t = \"\\u{41}ria == \\u{2764}\";\n    assert t == \"Aria == ❤\";\n}\n"
  },
  {
    "path": "tests/http_get_headers.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: FLAKEY\n\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\nimport * from aria.network.retry;\n\nfunc main() {\n    val request = Request.new(\"https://httpbin.org/headers\");\n    request.headers[\"User-Agent\"] = \"Aria\";\n    request.headers[\"Custom-Header\"] = \"Answer_Is_42\";\n\n    val result = retry(|| => request.get(), |result| => {\n        match result {\n            case Ok(response) => {\n                val code = response.status_code;\n                return code == 200 || code == 503;\n            }\n        } else {\n            return false;\n        }\n    });\n\n    result = result.unwrap_Pass()!;\n    if result.status_code == 503 {\n        println(\"Service Unavailable, try again later\");\n        return true;\n    }\n    val json_result = JsonValue.parse(result.content)!;\n\n    val json_map = json_result.unwrap_Object();\n    val json_headers = json_map[\"headers\"].unwrap_Object();\n    assert json_headers[\"User-Agent\"].unwrap_String() == \"Aria\";\n    assert json_headers[\"Custom-Header\"].unwrap_String() == \"Answer_Is_42\";\n}\n"
  },
  {
    "path": "tests/http_post.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: FLAKEY\n\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\nimport * from aria.network.retry;\n\nfunc main() {\n    val request = Request.new(\"https://httpbin.org/post\");\n\n    val result = retry(|| => request.post(\"hello world\"), |result| => {\n        match result {\n            case Ok(response) => {\n                val code = response.status_code;\n                return code == 200 || code == 503;\n            }\n        } else {\n            return false;\n        }\n    });\n\n    result = result.unwrap_Pass()!;\n    if result.status_code == 503 {\n        println(\"Service Unavailable, try again later\");\n        return true;\n    }\n\n    val json_result = JsonValue.parse(result.content)!;\n    val json_map = json_result.unwrap_Object();\n    val json_data = json_map[\"data\"].unwrap_String();\n    assert json_data == \"hello world\";\n}\n"
  },
  {
    "path": "tests/http_post_json.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: FLAKEY\n\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\nimport Map from aria.structures.map;\nimport * from aria.network.retry;\n\nfunc main() {\n    val request = Request.new(\"https://httpbin.org/post\");\n\n    val result = retry(|| => request.post_as_json(Map.new() {\n        [\"message\"] = \"hello world\",\n    }), |result| => {\n        match result {\n            case Ok(response) => {\n                val code = response.status_code;\n                return code == 200 || code == 503;\n            }\n        } else {\n            return false;\n        }\n    });\n\n    result = result.unwrap_Pass()!;\n    if result.status_code == 503 {\n        println(\"Service Unavailable, try again later\");\n        return true;\n    }\n    val json_result = JsonValue.parse(result.content)!.flatten();\n\n    assert json_result[\"json\"][\"message\"] == \"hello world\";\n}\n"
  },
  {
    "path": "tests/http_request_custom_status.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: FLAKEY\n\nimport Request from aria.network.request;\nimport * from aria.network.retry;\n\nfunc main() {\n    val request = Request.new(\"https://httpbin.org/status/418\");\n\n    val result = retry(|| => request.get(), |result| => {\n        match result {\n            case Ok(response) => {\n                val code = response.status_code;\n                return code == 418 || code == 503;\n            }\n        } else {\n            return false;\n        }\n    });\n\n    result = result.unwrap_Pass()!;\n    if result.status_code == 503 {\n        println(\"Service Unavailable, try again later\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "tests/http_simple_get.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: FLAKEY\n\nimport Request from aria.network.request;\nimport * from aria.network.retry;\n\nfunc main() {\n    val request = Request.new(\"https://www.rust-lang.org/\");\n    val response = retry(|| => request.get(), |result| => {\n        match result {\n            case Ok(response) => {\n                val code = response.status_code;\n                return code == 200 || code == 503;\n            }\n        } else {\n            return false;\n        }\n    });\n\n    response = response.unwrap_Pass()!;\n    if response.status_code == 503 {\n        println(\"Service Unavailable, try again later\");\n        return true;\n    }\n\n    assert response.headers[\"content-type\"].contains(\"html\");\n    assert response.content.contains(\"<html\");\n}\n"
  },
  {
    "path": "tests/identifier_casing.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val abc = 1;\n    val AbC = 2;\n    val aBC = 3;\n    val ABc = 4;\n    assert(abc == 1);\n    assert(AbC == 2);\n    assert(aBC == 3);\n    assert(ABc == 4);\n}\n"
  },
  {
    "path": "tests/identifier_syntax.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val 🇮🇹 = 1_861;\n    assert(🇮🇹 == 1861);\n    val 😎 = 1;\n    assert(😎 == 1);\n    val 📦 = 3;\n    assert(📦 == 3);\n    val 💯 = 100;\n    assert(💯 == 100);\n    val αΞж = 123;\n    assert(αΞж == 123);\n    val $_a = 321;\n    assert($_a == 321);\n    val _a$ = 213;\n    assert(_a$ == 213);\n}\n"
  },
  {
    "path": "tests/if_assign_val.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc return_something(x) {\n    return 42;\n}\n\nfunc main() {\n    val value = return_something(5);\n    if value == 43 {\n        assert false;\n    } else {\n        value = 41;\n    }\n\n    assert value == 41;\n}\n"
  },
  {
    "path": "tests/if_false.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val n = 0;\n    if false {\n        n = 1;\n    } else {\n        n = 2;\n    }\n    assert n == 2;\n}\n"
  },
  {
    "path": "tests/if_postfix_obj.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc obj() {\n    val check = false;\n    if Box(){.x = true}.x {\n        check = true;\n    }\n\n    return check;\n}\n\nfunc list() {\n    val check = false;\n    if []{[0] = true}[0] {\n        check = true;\n    }\n\n    return check;\n}\n\nfunc main() {\n    assert obj();\n    assert list();\n}\n"
  },
  {
    "path": "tests/if_takes_else.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 4;\n\n    if x == 1 {\n        assert false;\n    } elsif x == 2 {\n        assert false;\n    } elsif x == 3 {\n        assert false;\n    } else {\n        x;\n    }\n}\n"
  },
  {
    "path": "tests/if_takes_elsif.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 3;\n\n    if x == 1 {\n        assert false;\n    } elsif x == 2 {\n        assert false;\n    } elsif x == 3 {\n        x;\n    } else {\n        assert false;\n    }\n}\n"
  },
  {
    "path": "tests/if_takes_if.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 1;\n\n    if x == 1 {\n        x;\n    } elsif x == 2 {\n        assert false;\n    } elsif x == 3 {\n        assert false;\n    } else {\n        assert false;\n    }\n}\n"
  },
  {
    "path": "tests/if_true.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val n = 0;\n    if true {\n        n = 1;\n    } else {\n        n = 2;\n    }\n    assert n == 1;\n}\n"
  },
  {
    "path": "tests/implicit_is_X.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum HasCases {\n    case A(Int),\n    case B,\n    case C(String),\n    case D,\n    case E(HasCases)\n}\n\nfunc main() {\n    val ev = HasCases::A(123);\n    \n    assert ev.is_A();\n    assert !ev.is_B();\n    assert !ev.is_C();\n    assert !ev.is_D();\n    assert !ev.is_E();\n    assert ev.unwrap_A() == 123;\n\n    ev = HasCases::B;\n    assert !ev.is_A();\n    assert ev.is_B();\n    assert !ev.is_C();\n    assert !ev.is_D();\n    assert !ev.is_E();\n\n    ev = HasCases::C(\"hello\");\n    assert !ev.is_A();\n    assert !ev.is_B();\n    assert ev.is_C();\n    assert !ev.is_D();\n    assert !ev.is_E();\n    assert ev.unwrap_C() == \"hello\";\n\n    ev = HasCases::D;\n    assert !ev.is_A();\n    assert !ev.is_B();\n    assert !ev.is_C();\n    assert ev.is_D();\n    assert !ev.is_E();\n\n    ev = HasCases::E(HasCases::B);\n    assert !ev.is_A();\n    assert !ev.is_B();\n    assert !ev.is_C();\n    assert !ev.is_D();\n    assert ev.is_E();\n    assert ev.unwrap_E().is_B();\n}\n"
  },
  {
    "path": "tests/import_all.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport * from all.source;\n\nfunc main() {\n    assert something(3,5) == 7;\n    assert something_else(1,2,3) == 5;\n\n    val st = SomeType.new();\n    st.do_something();\n    assert st.x == 3;\n}\n"
  },
  {
    "path": "tests/import_from.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Pair from example.pair.Pair;\n\nfunc main() {\n    val p = Pair.new(4,6);\n    assert p.max() == 6;\n\n    val q = example.pair.Pair.Pair.new(5,7);\n    assert q.max() == 7;\n}\n"
  },
  {
    "path": "tests/import_pair_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport example.pair.Pair;\n\nfunc main() {\n    val p = example.pair.Pair.Pair.new(4,5);\n\n    assert p.max() == 5;\n    assert p.swap().y == 4;\n}\n"
  },
  {
    "path": "tests/import_string_extension.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ext.string;\n\nfunc main() {\n    val s = \"hello\";\n    assert s.test_method() == 6;\n}\n"
  },
  {
    "path": "tests/import_test_things.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport * from test_things;\n\nfunc main() {\n    assert x == 1;\n    assert foo(3,4) == 7;\n    assert bar(5) == 6;\n    x = 2;\n    assert x == 2;\n    assert foo(3,4) == 7;\n    assert bar(5) == 6;\n}\n"
  },
  {
    "path": "tests/import_two_things.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport example.two.things;\n\nfunc main() {\n    val t1 = example.two.things.One.new(4);\n    assert t1.double() == 10;\n\n    val t2 = example.two.things.Two.new(7);\n    assert t2.half() == 3;\n}\n"
  },
  {
    "path": "tests/include_trivial_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Answer {\n    func answer() {\n        return 42;\n    }\n}\n\nstruct SomeType {\n    type func new(x) {\n        return alloc(This){\n            .x = x,\n        };\n    }\n\n    include Answer\n}\n\nstruct AnotherType : Answer {\n    type func new(x) {\n        return alloc(This){\n            .x = x,\n        };\n    }\n}\n\nfunc test_shorthand() {\n    val at = AnotherType.new(2);\n    assert at.x == 2;\n    assert at.answer() == 42;\n}\n\nfunc main() {\n    val st = SomeType.new(1);\n    assert st.x == 1;\n    assert st.answer() == 42;\n    test_shorthand();\n}\n\n"
  },
  {
    "path": "tests/index_get.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Increment {\n    operator [](n) {\n        return n + 1;\n    }\n}\n\nfunc main() {\n    val i = alloc(Increment);\n    assert i[0] == 1;\n    assert i[5] == 6;\n    assert i[i[0]] == 2;\n}\n"
  },
  {
    "path": "tests/index_operators_empty.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new(x) = alloc(This) {.x};\n\n    operator []() = this.x;\n\n    operator[]=(n) {\n        this.x += n;\n    }\n}\n\nfunc main() {\n    val f = Foo.new(10);\n\n    assert f[] == 10;\n\n    f[] = 3;\n    assert f[] == 13;\n\n    f[] = 7;\n    assert f[] == 20;\n}\n"
  },
  {
    "path": "tests/index_out_of_bounds_error.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4];\n    val caught = false;\n\n    try {\n        assert l[0] + l[10] == 11;\n    } catch e {\n        match e {\n            isa RuntimeError and case IndexOutOfBounds(n) => {\n                caught = n == 10;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/index_set.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct StorePairs {\n    type func new() {\n        return alloc(This) {\n            .pairs = [],\n        };\n    }\n\n    operator []=(key, val) {\n        val i = 0;\n        val append = true;\n        while i < this.pairs.len() {\n            if this.pairs[i][0] == key {\n                this.pairs[i][1] = val;\n                append = false;\n                break;\n            }\n            i = i + 1;\n        }\n        if append {\n            this.pairs.append([key,val]);\n        }\n    }\n\n    operator [](key) {\n        val i = 0;\n        while i < this.pairs.len() {\n            if this.pairs[i][0] == key {\n                return this.pairs[i][1];\n            }\n            i = i + 1;\n        }\n        return false;\n    }\n}\n\nfunc main() {\n    val p = StorePairs.new();\n    p[0] = 1;\n    assert p[0] == 1;\n    p[0] = 2;\n    assert p[0] == 2;\n    p[123] = \"hi\";\n    assert p[123] == \"hi\";\n    assert p[0] == 2;\n    assert p[true] == false;\n}\n"
  },
  {
    "path": "tests/index_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    operator [](...) {\n        return varargs.len();\n    }\n}\n\nfunc main() {\n    val f = alloc(Foo);\n\n    assert f[1,2,3] == 3;\n    assert f[3,2,1] == 3;\n\n    assert f[0] == 1;\n    assert f[32, 33] == 2;\n}"
  },
  {
    "path": "tests/inner_function.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    func foo(x,y) {\n        return x + y - 1;\n    }\n\n    assert foo(3,4) == 6;\n}\n"
  },
  {
    "path": "tests/inner_function_redef.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    func inner(a,b,c) {\n        return a + b * c;\n    }\n\n    assert inner(3,4,5) == 23;\n\n    func inner(a,b) {\n        return a * b;\n    }\n\n    assert inner(3,4) == 12;\n\n    func inner() {\n        return 42;\n    }\n\n    assert inner() == 42;\n}\n"
  },
  {
    "path": "tests/inner_is_closure.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 123;\nval y = 100;\n\nfunc main() {\n    val x = 321;\n\n    func foo(n) {\n        return n + x + y; \n    }\n\n    val bar = |n| => n + x + y;\n\n    assert foo(3) == 424;\n    assert bar(3) == 424;\n}\n"
  },
  {
    "path": "tests/inner_outer_loop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\n### TAGS: XFAIL\n\nimport aria.range.int_extension;\n\nval inner = 0;\nval outer = 0;\nfor i in 0.to(12) {\n    for i in 0.to(500) {\n        inner += 1;\n    }\n    outer += 1;\n}\n\nassert inner == 6000;\nassert outer == 12;\n"
  },
  {
    "path": "tests/inner_val.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval counter = 0;\n\nfunc next() {\n    counter = counter + 1;\n    return counter;\n}\n\nfunc new_val_decl() {\n    val buffer = [];\n    val n = next();\n    while true {\n        buffer.append(n);\n        val n = next();\n        if n == 5 {\n            break;\n        }\n    }\n    return buffer;\n}\n\nfunc reuse_val_decl() {\n    val buffer = [];\n    val n = next();\n    while true {\n        buffer.append(n);\n        n = next();\n        if n == 5 {\n            break;\n        }\n    }\n    return buffer;\n}\n\n\nfunc main() {\n    val data = new_val_decl();\n    assert data == [1, 1, 1, 1];\n    counter = 0;\n    data = reuse_val_decl();\n    assert data == [1, 2, 3, 4];\n}\n"
  },
  {
    "path": "tests/instant_from_unix_2024_12_29.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Instant from aria.date.instant;\n\nfunc main() {\n    val ts = 1735446958423;\n    val instant = Instant.new_with_utc_timestamp(ts);\n\n    assert instant.year == 2024;\n    assert instant.month == 12;\n    assert instant.day == 29;\n    assert instant.hour == 4;\n    assert instant.minute == 35;\n    assert instant.second == 58;\n}\n"
  },
  {
    "path": "tests/instant_from_unix_ts.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Instant from aria.date.instant;\n\nfunc main() {\n    val moment = Instant.new_with_utc_timestamp(1623602460000);\n    assert moment.year == 2021;\n    assert moment.month == 6;\n    assert moment.day == 13;\n    assert moment.hour == 16;\n    assert moment.minute == 41;\n    assert moment.second == 0;\n    assert moment.millisecond == 0;\n    assert \"{0}\".format(moment) == \"Jun 13 2021 16:41:00.000\";\n\n    moment = Instant.new_with_utc_timestamp(1736142835000);\n    assert moment.year == 2025;\n    assert moment.month == 1;\n    assert moment.day == 6;\n    assert moment.hour == 5;\n    assert moment.minute == 53;\n    assert moment.second == 55;\n    assert moment.millisecond == 0;\n\n    moment = Instant.new_with_utc_timestamp(-85399999000);\n    assert moment.year == 1967;\n    assert moment.month == 4;\n    assert moment.day == 18;\n    assert moment.hour == 13;\n    assert moment.minute == 46;\n    assert moment.second == 41;\n    assert moment.millisecond == 0;\n\n    moment = Instant.new_with_utc_timestamp(-783264174000);\n    assert moment.year == 1945;\n    assert moment.month == 3;\n    assert moment.day == 7;\n    assert moment.hour == 10;\n    assert moment.minute == 37;\n    assert moment.second == 6;\n    assert moment.millisecond == 0;\n\n    moment = Instant.new_with_utc_timestamp(-1);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 31;\n    assert moment.hour == 23;\n    assert moment.minute == 59;\n    assert moment.second == 59;\n    assert moment.millisecond == 999;\n\n    moment = Instant.new_with_utc_timestamp(-999);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 31;\n    assert moment.hour == 23;\n    assert moment.minute == 59;\n    assert moment.second == 59;\n    assert moment.millisecond == 1;\n\n    moment = Instant.new_with_utc_timestamp(-1000);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 31;\n    assert moment.hour == 23;\n    assert moment.minute == 59;\n    assert moment.second == 59;\n    assert moment.millisecond == 0;\n\n    moment = Instant.new_with_utc_timestamp(-1001);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 31;\n    assert moment.hour == 23;\n    assert moment.minute == 59;\n    assert moment.second == 58;\n    assert moment.millisecond == 999;\n\n    moment = Instant.new_with_utc_timestamp(-86400000);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 31;\n    assert moment.hour == 0;\n    assert moment.minute == 0;\n    assert moment.second == 0;\n    assert moment.millisecond == 0;\n\n    moment = Instant.new_with_utc_timestamp(-86400001);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 30;\n    assert moment.hour == 23;\n    assert moment.minute == 59;\n    assert moment.second == 59;\n    assert moment.millisecond == 999;\n\n    moment = Instant.new_with_utc_timestamp(-2678400000);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 1;\n    assert moment.hour == 0;\n    assert moment.minute == 0;\n    assert moment.second == 0;\n    assert moment.millisecond == 0;\n\n    moment = Instant.new_with_utc_timestamp(-1423503211);\n    assert moment.year == 1969;\n    assert moment.month == 12;\n    assert moment.day == 15;\n    assert moment.hour == 12;\n    assert moment.minute == 34;\n    assert moment.second == 56;\n    assert moment.millisecond == 789;\n}\n"
  },
  {
    "path": "tests/instant_now.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Instant from aria.date.instant;\n\nfunc main() {\n    val now = Instant.now();\n\n    assert now.year >= 2025;\n    assert now.month >= 1 && now.month <= 12;\n    assert now.day >= 1 && now.day <= 31;\n    assert now.hour >= 0 && now.hour <= 23;\n    assert now.minute >= 0 && now.minute <= 59;\n    assert now.second >= 0 && now.second <= 59;\n    assert now.millisecond >= 0 && now.millisecond <= 999;\n}\n"
  },
  {
    "path": "tests/instant_offset_breaks_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Instant from aria.date.instant;\n\nval a = Instant.new_with_utc_timestamp(0).with_timezone_offset(60);\nval b = Instant.new_with_timestamp_and_offset(0, 60);\n\nassert a == b;\n"
  },
  {
    "path": "tests/instant_with_tz_offset.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Instant from aria.date.instant;\n\nfunc main() {\n    val instant = Instant.new_with_timestamp_and_offset(1623602460000, -360);\n    assert instant.year == 2021;\n    assert instant.month == 6;\n    assert instant.day == 13;\n    assert instant.hour == 10;\n    assert instant.minute == 41;\n    assert instant.second == 0;\n    assert instant.millisecond == 0;\n\n    instant = Instant.new_with_timestamp_and_offset(1623602460000, 150);\n    assert instant.year == 2021;\n    assert instant.month == 6;\n    assert instant.day == 13;\n    assert instant.hour == 19;\n    assert instant.minute == 11;\n    assert instant.second == 0;\n    assert instant.millisecond == 0;\n}\n"
  },
  {
    "path": "tests/int_abs.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 3;\n    val y = -3;\n    assert y.abs() == x;\n    assert x.abs() == x;\n}"
  },
  {
    "path": "tests/int_arith.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc addition() {\n    assert 3 + 4 == 7;\n    assert 2 + 2 == 4;\n}\n\nfunc subtraction() {\n    assert 2 - 2 == 0;\n    assert 12 - 3 == 9;\n    assert 9 - 10 == -1;\n}\n\nfunc multiplication() {\n    assert 3 * 2 == 6;\n    assert 2 * 1 == 2;\n    assert 6 * 7 == 42;\n}\n\nfunc division() {\n    assert 8 / 4 == 2;\n    assert 7 / 2 == 3;\n    assert 5 / 1 == 5;\n}\n\nfunc remainder() {\n    assert 8 % 2 == 0;\n    assert 7 % 2 == 1;\n    assert 21 % 9 == 3;\n}\n\nfunc main() {\n    addition();\n    subtraction();\n    multiplication();\n    division();\n    remainder();\n}\n"
  },
  {
    "path": "tests/int_fp_int.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = 3;\n    assert a.float() == 3.0f;\n    assert a.float() isa Float;\n    a = 3.0f;\n    assert a.int() == 3;\n    assert a.int() isa Int;\n}\n\n"
  },
  {
    "path": "tests/int_index_operator.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Int {\n    operator[](index: Int) {\n        val n = 1 << index;\n        return (this & n) >> index;\n    }\n}\n\nval n = 0b1111000011101;\n\nassert n[0] == 1;\nassert n[1] == 0;\nassert n[2] == 1;\nassert n[3] == 1;\nassert n[4] == 1;\nassert n[5] == 0;\nassert n[6] == 0;\nassert n[7] == 0;\nassert n[8] == 0;\nassert n[9] == 1;\nassert n[10] == 1;\nassert n[11] == 1;\nassert n[12] == 1;\nassert n[13] == 0;\nassert n[14] == 0;\nassert n[15] == 0;\n# ... and so on and so forth ...\n"
  },
  {
    "path": "tests/int_notations.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = 123_456 + 1;\n    assert a == 1234_57;\n    val a = 0xF - 0xD;\n    assert a == 0b10;\n    val a = 3 * 4;\n    assert a == 12;\n}\n"
  },
  {
    "path": "tests/int_prettyprint_style.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = 1234;\n    val b = -35;\n\n    assert \"{0}\".format(a) == \"1234\";\n    assert \"{0:6}\".format(a) == \"001234\";\n    assert \"{0:2}\".format(a) == \"1234\";\n\n    assert \"0x{0:x}\".format(a) == \"0x4d2\";\n    assert \"0x{0:5x}\".format(a) == \"0x004d2\";\n\n    assert \"{0}\".format(b) == \"-35\";\n    assert \"{0:6}\".format(b) == \"-00035\";\n}\n"
  },
  {
    "path": "tests/int_range.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\nimport aria.iterator.mixin;\n\nfunc main() {\n    val range = Range.from(3).through(5);\n    assert range.contains(3);\n    assert range.contains(4);\n    assert range.contains(5);\n\n    assert !range.contains(2);\n    assert !range.contains(6);\n\n    val sum = 0;\n    for item in range {\n        sum = sum + item;\n    }\n\n    assert sum == 12;\n\n    val list = range.iterator().to_list();\n    assert list == [3,4,5];\n}\n\n"
  },
  {
    "path": "tests/int_range_ops.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nfunc main() {\n    val r1 = Range.from(3).through(5);\n    val r2 = Range.from(6).through(10);\n    val r3 = Range.from(1).through(7);\n\n    val r2_u_r3 = r2.union(r3);\n    assert r2_u_r3.iterator().to_list() == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n    val r1_i_r2 = r1.intersection(r2);\n    assert r1_i_r2.length() == 0;\n\n    val r1_i_r3 = r1.intersection(r3);\n    assert r1_i_r3.iterator().to_list() == [3, 4, 5];\n\n    val r1_u_3 = r1.union(r3);\n    assert r1_u_3.iterator().to_list() == [1, 2, 3, 4, 5, 6, 7];\n}\n"
  },
  {
    "path": "tests/int_range_step.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nfunc main() {\n    val range = Range.from(3).through(20);\n\n    val sum = 0;\n    for item in range.step(5) {\n        sum = sum + item;\n    }\n    assert sum == 42;\n}"
  },
  {
    "path": "tests/int_range_where_iter.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nfunc main() {\n    val range = Range.from(3).through(20);\n\n    val count = 0;\n    for item in range.iterator().where(|x| => x == 10) {\n        assert item == 10;\n        count = count + 1;\n    }\n\n    assert count == 1;\n}\n"
  },
  {
    "path": "tests/int_shift_test.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val n = 0b0011001100010;\n    val shl = n >> 3;\n    assert shl == 0b0011001100;\n    val shn = n << 4;\n    assert shn == 0b00110011000100000;\n}"
  },
  {
    "path": "tests/int_wraps.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = 0x7FFFFFFFFFFFFFFF;\n    assert(a + 1 < 0);\n    assert(a * 2 == -2);\n    assert(a-a*2 == -9223372036854775807);\n    assert(a/2 == 4611686018427387903);\n    assert(a % 37 == 5);\n}\n"
  },
  {
    "path": "tests/invalid_fileopen_throws.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val thrown = false;\n\n    try {\n        # this path should be invalid on pretty much any system that exists and matters\n        val file = File.open(\"@:?/\\.nonexistent_file.txt\", File.OpenMode.new().read());\n    } catch e {\n        thrown = true;\n    }\n\n    assert(thrown);\n}\n"
  },
  {
    "path": "tests/invalid_utf8_bytes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    try {\n        val bytes = [240, 159, 150];\n        val str = String.new_with_bytes(bytes);\n        assert false;\n    } catch e {\n        assert e isa String.EncodingError;\n        assert e.msg == \"invalid utf8\";\n    }\n}\n"
  },
  {
    "path": "tests/isa_intersection.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok,err from aria.core.result;\n\nmixin DefaultAlloc {\n    type func new() {\n        return alloc(This);\n    }\n}\n\nmixin A {\n    func double(x) {\n        return x + x;\n    }\n}\n\nmixin B {\n    func triple(x) {\n        return x + x + x;\n    }\n}\n\nstruct S {\n    include A\n    include B\n    include DefaultAlloc\n}\n\nstruct T {\n    include A\n    include DefaultAlloc\n}\n\nstruct U {\n    include B\n    include DefaultAlloc\n}\n\nfunc do_math(x: A&B) {\n    return x.double(2) + x.triple(3);\n}\n\nfunc try_doing_math(x) {\n    try {\n        return ok(do_math(x));\n    } catch e {\n        return err(e);\n    }\n}\n\nfunc main() {\n    val s = S.new();\n    val t = T.new();\n    val u = U.new();\n\n    val s_math = try_doing_math(s);\n    val t_math = try_doing_math(t);\n    val u_math = try_doing_math(u);\n\n    assert s_math.is_Ok();\n    assert s_math! == 13;\n\n    assert u_math.is_Err();\n    assert t_math.is_Err();\n}\n"
  },
  {
    "path": "tests/isa_match.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 123;\n    val hit = false;\n    match x {\n        isa Bool => { assert(false); },\n        isa List => { assert(false); },\n        isa Int => { hit = true; },\n    } else {\n        assert(false);\n    }\n\n    assert hit;\n}\n"
  },
  {
    "path": "tests/isa_mixin_union.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok,err from aria.core.result;\n\nmixin A {\n    func double(x) {\n        return x + x;\n    }\n}\n\nmixin B {\n    func double(x) {\n        return x * 2;\n    }\n}\n\nstruct S {\n    include A\n}\n\nstruct T {\n    include B\n}\n\nstruct U {}\n\nfunc foo(x: A|B) {\n    return x.double(5);\n}\n\nfunc try_double(x) {\n    try {\n        return ok(foo(x));\n    } catch e {\n        return err(e);\n    }\n}\n\nfunc main() {\n    val s = alloc(S);\n    val t = alloc(T);\n    val u = alloc(U);\n\n    val double_s = try_double(s);\n    val double_t = try_double(t);\n    val double_u = try_double(u);\n\n    assert double_s.is_Ok();\n    assert double_s! == 10;\n\n    assert double_t.is_Ok();\n    assert double_t! == 10;\n\n    assert double_u.is_Err();\n}\n"
  },
  {
    "path": "tests/isa_operator.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {}\n\nfunc main() {\n    assert 3 isa Int;\n    assert 3.14f isa Float;\n    assert false isa Bool;\n\n    assert !(false isa String);\n    assert !(\"hello\" isa Foo);\n\n    assert alloc(Foo) isa (Int|Foo);\n    assert false isa (Bool|String);\n}\n"
  },
  {
    "path": "tests/iter_enum.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Enumerate from aria.iterator.enumerate;\n\nfunc main() {\n    val l = [1,2,3,4,5,6,7,8,9];\n    for item in Enumerate.new(l) {\n        assert item.index + 1 == item.value;\n    }\n}\n"
  },
  {
    "path": "tests/iter_zip.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Zip from aria.iterator.zip;\nimport aria.iterator.mixin;\n\nfunc add(x,y) {\n    return x + y;\n}\n\nfunc main() {\n    val l1 = [1,2,3,4,5];\n    val l2 = [4,3,2,0];\n    val l3 = [3,3,3,4];\n    val count = 0;\n\n    val z = Zip.new(l1,l2,l3);\n    for item in z {\n        val sum = item.reduce(add,0);\n        assert sum == 8;\n        count = count + 1;\n    }\n\n    assert count == 4;\n}\n"
  },
  {
    "path": "tests/iterable_skip.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nfunc main() {\n    val l = [1,2,3,4,5,6,7,8,9,10];\n    assert l.iterator().skip(5).nth(0)! == 6;\n    assert l.iterator().skip(5).nth(1)! == 7;\n\n    assert l.iterator().skip(10).first() == Maybe::None;\n    assert l.iterator().skip(15).first() == Maybe::None;\n\n    assert l.iterator().skip(0).first()! == 1;\n\n    assert l.iterator().skip(3).skip(4).first()! == 8;\n}\n"
  },
  {
    "path": "tests/iterable_truncate.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nfunc main() {\n    val l = [1,2,3,4,5,6,7,8,9,10];\n\n    assert l.iterator().truncate(5).sum() == 15;\n    assert l.iterator().truncate(0).sum() == 0;\n    assert l.iterator().truncate(1000).sum() == 55;\n\n    assert l.iterator().truncate(3).truncate(2).sum() == 3;\n}\n"
  },
  {
    "path": "tests/iterator_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nfunc is_even(x) {\n    return x % 2 == 0;\n}\n\nfunc add_one(x) {\n    return x + 1;\n}\n\nfunc main() {\n    val l = [1,2,3,4,5,6,7,8,9,10];\n\n    val sum = 0;\n    for item in l.iterator().where(is_even).map(add_one) {\n        sum = sum + item;\n    }\n    assert sum == 35;\n\n    assert (l.iterator().find(is_even) ?? -1) == 2;\n    assert (l.iterator().position(is_even) ?? -1) == 1;\n\n    assert l.iterator().sum() == 55;\n    assert l.iterator().sum(10) == 65;\n    assert l.iterator().product() == 3628800;\n    assert l.iterator().product(2) == 7257600;\n    assert (l.iterator().max() ?? -1) == 10;\n    assert (l.iterator().min() ?? -1) == 1;\n    assert l.iterator().count() == 10;\n\n    val l = [42, 16, 55, 120, 5];\n    assert (l.iterator().first() ?? -1) == 42;\n    assert (l.iterator().last() ?? -1) == 5;\n    assert (l.iterator().nth(2) ?? -1) == 55;\n}\n"
  },
  {
    "path": "tests/iterator_type_mismatch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct MyIterator {\n    func next() {\n        return 12; # not a Maybe :(\n    }\n\n    func iterator() = this;\n\n    type func new() = alloc(This);\n}\n\nfunc main() {\n    val caught = false;\n\n    val it = MyIterator.new();\n    try {\n        for number in it {\n            assert false; # should never get here\n        }\n    } catch e {\n        assert e isa RuntimeError;\n        assert e.is_UnexpectedType();\n        caught = true;\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/json_flatten.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport JsonValue from aria.json.value;\nimport aria.json.parser;\n\nfunc main() {\n    val json_string = '{ \"key1\": [1,2,3], \"key2\": {\"a\":1, \"b\":false, \"c\": \"hello world\"} }';\n\n    val json_object = JsonValue.parse(json_string)!;\n    val json_flat = json_object.flatten();\n\n    assert json_flat[\"key1\"][0] == 1;\n    assert json_flat[\"key1\"][1] == 2;\n    assert json_flat[\"key1\"][2] == 3;\n    assert json_flat[\"key1\"].len() == 3;\n\n    assert json_flat[\"key2\"][\"a\"] == 1;\n    assert json_flat[\"key2\"][\"b\"] == false;\n    assert json_flat[\"key2\"][\"c\"] == \"hello world\";\n    assert json_flat[\"key2\"].len() == 3;\n\n    assert json_flat.len() == 2;\n}\n"
  },
  {
    "path": "tests/json_parse_array.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport JsonValue from aria.json.parser;\n\nfunc main() {\n    val json_object = JsonValue.parse('[1, 2, \"hello\", 3.14]')!;\n\n    assert json_object.is_Array();\n    val array = json_object.unwrap_Array();\n    assert array.len() == 4;\n\n    assert array[0].is_Number();\n    assert array[0].unwrap_Number() == 1.0f;\n    assert array[1].is_Number();\n    assert array[1].unwrap_Number() == 2.0f;\n    assert array[2].is_String();\n    assert array[2].unwrap_String() == \"hello\";\n    assert array[3].is_Number();\n    assert array[3].unwrap_Number() == 3.14f;\n}\n"
  },
  {
    "path": "tests/json_parse_nested.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport JsonValue from aria.json.parser;\n\nfunc main() {\n    val json_object = JsonValue.parse('{\"l\": [1, 2, 3], \"o\": {\"key1\": 1, \"key2\": \"value2\", \"key3\": [4,5,6]}}')!;\n\n    assert json_object.is_Object();\n    val map = json_object.unwrap_Object();\n    assert map[\"l\"].is_Array();\n    val array = map[\"l\"].unwrap_Array();\n    assert array.len() == 3;\n    assert array[0].is_Number();\n    assert array[0].unwrap_Number() == 1.0f;\n    assert array[1].is_Number();\n    assert array[1].unwrap_Number() == 2.0f;\n    assert array[2].is_Number();\n    assert array[2].unwrap_Number() == 3.0f;\n    assert map[\"o\"].is_Object();\n    val inner_map = map[\"o\"].unwrap_Object();\n    assert inner_map[\"key1\"].is_Number();\n    assert inner_map[\"key1\"].unwrap_Number() == 1.0f;\n    assert inner_map[\"key2\"].is_String();\n    assert inner_map[\"key2\"].unwrap_String() == \"value2\";\n    assert inner_map[\"key3\"].is_Array();\n    val inner_array = inner_map[\"key3\"].unwrap_Array();\n    assert inner_array.len() == 3;\n    assert inner_array[0].is_Number();\n    assert inner_array[0].unwrap_Number() == 4.0f;\n    assert inner_array[1].is_Number();\n    assert inner_array[1].unwrap_Number() == 5.0f;\n    assert inner_array[2].is_Number();\n    assert inner_array[2].unwrap_Number() == 6.0f;\n}\n"
  },
  {
    "path": "tests/json_parse_wellknown.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport JsonValue from aria.json.parser;\n\nfunc main() {\n    val json_object = JsonValue.parse('[true, false, null]')!;\n\n    assert json_object.is_Array();\n    val array = json_object.unwrap_Array();\n    assert array.len() == 3;\n    assert array[0].is_Boolean();\n    assert array[0].unwrap_Boolean() == true;\n    assert array[1].is_Boolean();\n    assert array[1].unwrap_Boolean() == false;\n    assert array[2].is_Null();    \n}\n"
  },
  {
    "path": "tests/lambda_f_block.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val f = |x,y| => {\n        if x > y {\n            return x;\n        } else {\n            return y;\n        }\n    };\n\n    assert f(3,4) == 4;\n    assert f(2,0) == 2;\n}\n"
  },
  {
    "path": "tests/lambda_f_define.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val double = |x| => x * 2;\n\n    assert double(3) == 6;\n    assert double(\"a\") == \"aa\";\n}\n"
  },
  {
    "path": "tests/lambda_f_global.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval n = 3;\n\nval foo = |x| => x + n;\n\nfunc main() {\n    assert foo(4) == 7;\n    n = 2;\n    assert foo(4) == 6;\n    assert foo(6) == 8;\n}\n"
  },
  {
    "path": "tests/lambda_refers_to_uplevel.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval q = 1;\n\nfunc foo(x,y,z) {\n    return |a| => a + y - z * q;\n}\n\nfunc main() {\n    val f = foo(3,4,5);\n    assert f(3) == 2;\n    assert f(4) == 3;\n    q = 2;\n    assert f(5) == -1;\n}\n"
  },
  {
    "path": "tests/large_hex_int.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval n = 0x94d049bb133111eb;\nassert n == -7723592293110705685;\n"
  },
  {
    "path": "tests/large_negative_literal.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 0x7FFFFFFFFFFFFFFF;\n    assert x==9223372036854775807;\n    assert x+1==-9223372036854775808;\n}\n"
  },
  {
    "path": "tests/list_append.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4];\n    assert l.len() == 4;\n    assert l[0] == 1;\n    assert l[1] == 2;\n    assert l[2] == 3;\n    assert l[3] == 4;\n    l.append(5).append(6);\n    assert l.len() == 6;\n    assert l[3] == 4;\n    assert l[4] == 5;\n    assert l[5] == 6;\n}\n"
  },
  {
    "path": "tests/list_as_map_key.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\nimport aria.structures.hash.list;\n\nfunc main() {\n    val m = Map.new();\n    val l1 = [1,2,3];\n    val l2 = [4,5,6];\n    m[l1] = 1+2+3;\n    m[l2] = 4+5+6;\n\n    assert m[l1] == 6;\n    assert m[l2] == 15;\n\n    assert m.get([1,2,3])! == 6;\n    assert m.get([4,5,6])! == 15;\n\n    assert m.get([3,2,1]).is_None();\n    assert m.get([]).is_None();\n\n    assert m.len() == 2;\n}\n"
  },
  {
    "path": "tests/list_contains.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {}\n\nfunc main() {\n    val l = [\"hello\", false, 123, alloc(Foo), 5];\n\n    assert l.contains(false);\n    assert l.contains(\"hello\");\n    assert !l.contains(true);\n    assert !l.contains(456);\n    assert l.contains(5);\n}\n"
  },
  {
    "path": "tests/list_custom_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,5];\n    l.sum = 11;\n    l.max = 5;\n\n    assert l.sum == 11;\n    assert l.max == 5;\n\n    assert l.len() == 4;\n}\n"
  },
  {
    "path": "tests/list_drop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4,5];\n    assert l.len() == 5;\n\n    assert l.drop() == 5;\n    assert l.len() == 4;\n    assert l[0] == 1;\n    assert l[1] == 2;\n    assert l[2] == 3;\n    assert l[3] == 4;\n\n    assert l.drop() == 4;\n    assert l.len() == 3;\n    assert l[0] == 1;\n    assert l[1] == 2;\n    assert l[2] == 3;\n\n    l.append(5);\n    assert l.len() == 4;\n    assert l[0] == 1;\n    assert l[1] == 2;\n    assert l[2] == 3;\n    assert l[3] == 5;\n}\n"
  },
  {
    "path": "tests/list_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n: Int) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return rhs == this.n;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    val l1 = [1,2,3,4,5];\n    val l2 = [Integer.new(1), 2, 3, Integer.new(4), 5];\n    val l3 = [Integer.new(1), 2, 3, 5, Integer.new(5)];\n\n    assert l1 == l2;\n    assert l2 == l1;\n\n    assert l1 != l3;\n    assert l3 != l1;\n\n    assert l2 != l3;\n    assert l3 != l2;\n}\n"
  },
  {
    "path": "tests/list_filled.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval l = List.filled(false, 100);\n\nassert l.len() == 100;\nfor item in l {\n    assert item == false;\n}\n"
  },
  {
    "path": "tests/list_for_loop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val sum = 0;\n    val l = [1,2,3,4,5];\n    for item in l {\n        sum = sum + item;\n    }\n    assert sum == 15;\n}\n"
  },
  {
    "path": "tests/list_functional.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nfunc is_gt_10(x) {\n    return x > 10;\n}\n\nfunc test_any() {\n    val l = [1,2,3,4,5,6];\n    assert l.iterator().any(|x| => x > 5) == true;\n    assert l.iterator().any(is_gt_10) == false;\n}\n\nfunc is_lt_10(x) {\n    return x < 10;\n}\n\nfunc test_all() {\n    val l = [1,2,3,4,5,6];\n    assert l.iterator().all(is_lt_10) == true;\n    assert l.iterator().all(|x| => x > 5) == false;\n}\n\nfunc test_where() {\n    val l = [1,2,3,4,5,6];\n    assert l.where(is_gt_10).to_list() == [];\n    assert l.where(|x| => x > 5).to_list() == [6];\n}\n\nfunc do_the_thing(x) {\n    return 2 * x + 1;\n}\n\nfunc test_map() {\n    val l = [1,2,3,4,5,6];\n    assert l.map(do_the_thing).to_list() == [3,5,7,9,11,13];\n    assert l.map(|x| => x > 5).to_list() == [false,false,false,false,false,true];\n}\n\nfunc main() {\n    test_any();\n    test_all();\n    test_where();\n    test_map();\n}\n"
  },
  {
    "path": "tests/list_hash.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.structures.hash.list;\n\nfunc main() {\n    val l1 = [1,2,3];\n    val l2 = [\"1\", \"2\", \"3\"];\n    val l3 = [3,2,1];\n    val l4 = [];\n\n    assert l1.hash() != l2.hash();\n    assert l1.hash() != l3.hash();\n    assert l1.hash() != l4.hash();\n    assert l2.hash() != l3.hash();\n    assert l2.hash() != l4.hash();\n    assert l3.hash() != l4.hash();\n\n    assert l1.hash() == l1.hash();\n    assert l2.hash() == l2.hash();\n    assert l3.hash() == l3.hash();\n    assert l4.hash() == l4.hash();\n}\n"
  },
  {
    "path": "tests/list_iter_map.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Enumerate from aria.iterator.enumerate;\nimport aria.iterator.mixin;\n\nfunc double(n) {\n    return n + n;\n}\n\nfunc main() {\n    val sum = 0;\n    val list = [1,2,3,4,5,6];\n    for item in Enumerate.new(list.iterator().map(double)) {\n        val original_number = list[item.index];\n        val new_number = item.value;\n\n        assert new_number == double(original_number); \n        sum += new_number;\n    }\n\n    assert sum == 42;\n}\n"
  },
  {
    "path": "tests/list_join.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4];\n\n    assert l.join() == \"1, 2, 3, 4\";\n    assert l.join(\"..\") == \"1..2..3..4\";\n    assert l.join(\" - \") == \"1 - 2 - 3 - 4\";\n\n    assert [].join() == \"\";\n    assert [1].join() == \"1\";\n    assert [].join(\"..\") == \"\";\n    assert [1].join(\"..\") == \"1\";\n}\n"
  },
  {
    "path": "tests/list_length.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val lst_empty = [];\n    val lst_one = [1];\n    val lst_three = [1,2,3];\n    val lst_nested = [lst_empty, lst_one, lst_three, false];\n\n    assert lst_empty.len() == 0;\n    assert lst_one.len() == 1;\n    assert lst_three.len() == 3;\n\n    assert lst_nested.len() == 4;\n    assert lst_nested[0].len() == 0;\n    assert lst_nested[1].len() == 1;\n    assert lst_nested[2].len() == 3;\n}\n"
  },
  {
    "path": "tests/list_mul_op.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3];\n    assert l * 0 == [];\n    assert l * 1 == [1,2,3];\n    assert l * 2 == [1,2,3,1,2,3];\n    assert l * 3 == [1,2,3,1,2,3,1,2,3];\n    assert l * 4 == [1,2,3,1,2,3,1,2,3,1,2,3];\n\n    assert 0 * l == [];\n    assert 1 * l == [1,2,3];\n    assert 2 * l == [1,2,3,1,2,3];\n    assert 3 * l == [1,2,3,1,2,3,1,2,3];\n    assert 4 * l == [1,2,3,1,2,3,1,2,3,1,2,3];\n}\n"
  },
  {
    "path": "tests/list_negative_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = [1,2,3,4,5];\n\nassert x[-1] == 5;\nassert x[-2] == 4;\nassert x[-5] == 1;\n\ntry {\n    println(x[-6]);\n} catch e {\n    assert e isa RuntimeError;\n    assert e.is_IndexOutOfBounds();\n}\n\nx[-1] = 10;\nassert x[4] == 10;\nx[-2] = 20;\nassert x[3] == 20;\n\ntry {\n    x[-10] = 50;\n} catch e {\n    assert e isa RuntimeError;\n    assert e.is_IndexOutOfBounds();\n}\n\n"
  },
  {
    "path": "tests/list_op_add.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l1 = [1,2,3,4];\n    val l2 = [3,2,1];\n\n    val l3 = l1 + l2;\n    assert l3.len() == l1.len() + l2.len();\n\n    assert l3[0] == 1;\n    assert l3[1] == 2;\n    assert l3[2] == 3;\n    assert l3[3] == 4;\n    assert l3[4] == 3;\n    assert l3[5] == 2;\n    assert l3[6] == 1;\n}\n"
  },
  {
    "path": "tests/list_prettyprint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type val COUNTER = 1;\n\n    type func new(x) {\n        val f = alloc(This){\n            .counter = Foo.COUNTER,\n            .x = x,\n        };\n        Foo.COUNTER = Foo.COUNTER + 1;\n        return f;\n    }\n\n    func prettyprint() {\n        return \"Foo({0},{1})\".format(this.counter,this.x);\n    }\n}\n\nfunc main() {\n    val l = [Foo.new(\"a\"),Foo.new(\"b\"),Foo.new(\"c\")];\n    val ls = \"list of Foo = {0}\".format(l);\n    assert ls == \"list of Foo = [Foo(1,a), Foo(2,b), Foo(3,c)]\";\n}\n"
  },
  {
    "path": "tests/list_product_negative.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nassert [1,2,3]*-1 == [];\nassert [[1,2,3],[4,5,6],1,2,3]*-5 == [];\nassert [\"a\",\"b\",\"c\"]*0 == [];\n"
  },
  {
    "path": "tests/list_search.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val list = [3,7,11,16,19,33,46,55,91,328,410,510,613];\n\n    assert list.binary_search(21).is_None();\n    assert list.binary_search(33).is_Some();\n    assert list.binary_search(33).unwrap_Some() == 5;\n    assert list[5] == 33;\n}\n"
  },
  {
    "path": "tests/list_sorting.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val list = [6,7,2,5,12,21,78,32,1];\n    list.quicksort();\n    assert list[0] == 1;\n    assert list[1] == 2;\n    assert list[2] == 5;\n    assert list[3] == 6;\n    assert list[4] == 7;\n    assert list[5] == 12;\n    assert list[6] == 21;\n    assert list[7] == 32;\n    assert list[8] == 78;\n}\n"
  },
  {
    "path": "tests/list_sorting_with_cmp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val list = [6,7,2,5,12,21,78,32,1];\n    list.quicksort_with_comparator(|x,y| => x > y);\n    assert list[0] == 78;\n    assert list[1] == 32;\n    assert list[2] == 21;\n    assert list[3] == 12;\n    assert list[4] == 7;\n    assert list[5] == 6;\n    assert list[6] == 5;\n    assert list[7] == 2;\n    assert list[8] == 1;\n}\n"
  },
  {
    "path": "tests/list_where_iterator.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nfunc is_even(n) {\n    return n % 2 == 0;\n}\n\nfunc main() {\n    val l = [1,2,3,4,5,6,7,8,9,10];\n\n    val sum = 0;\n    for item in l.iterator().where(is_even) {\n        sum = sum + item;\n        assert is_even(item);\n    }\n\n    assert sum == 30;\n}\n"
  },
  {
    "path": "tests/list_write_out_of_bounds.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    try {\n        [][10] = 42;\n    } catch e {\n        assert e isa RuntimeError;\n        assert e.unwrap_IndexOutOfBounds() == 10;\n    }\n}\n"
  },
  {
    "path": "tests/local_define_type_mismatch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val caught = false;\n    val x: Int = 1;\n\n    try {\n        x = false;\n        println(x == 1); # need to use \"x\", otherwise it's dropped by the optimizer\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/local_typehint_any.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x: Any = 1;\n    assert x == 1;\n    x = 2;\n    assert x == 2;\n    x = false;\n    assert x == false;\n    x = \"hello\";\n    assert x == \"hello\";\n    x = main;\n}\n"
  },
  {
    "path": "tests/local_write_type_mismatch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val caught = false;\n\n    try {\n        val x: Int = \"a\";\n        println(x == 1); # need to use \"x\", otherwise it's dropped by the optimizer\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/lr_shift_custom_op.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Shifter {\n    type func new() {\n        return alloc(This){\n            .offset = 0,\n        };\n    }\n\n    operator << (n: Int) {\n        return alloc(Shifter) {\n            .offset = this.offset - n,\n        };\n    }\n\n    operator >> (n: Int) {\n        return alloc(Shifter) {\n            .offset = this.offset + n,\n        };\n    }\n}\n\nfunc main() {\n    val s = Shifter.new();\n\n    s = s << 1;\n    assert s.offset == -1;\n\n    s = s >> 6;\n    assert s.offset == 5;\n\n    s = s << 3;\n    assert s.offset == 2;\n\n    s = (s << 3) >> 4;\n    assert s.offset == 3;\n\n    s = s << 10;\n    assert s.offset == -7;\n}\n"
  },
  {
    "path": "tests/lt_gt_comp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 3;\n    val y = 5;\n\n    assert x < y;\n    assert y > x;\n}\n"
  },
  {
    "path": "tests/lte_gte_comp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = 5;\n    val b = 8;\n\n    assert a <= a;\n    assert b >= b;\n    assert a >= a;\n    assert b <= b;\n\n    assert a <= b;\n    assert b >= a;\n}\n"
  },
  {
    "path": "tests/map_0_capacity.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport Map from aria.structures.map;\n\nval m = Map.new_with_capacity(0);\nm[\"apple\"] = 5;\nassert m[\"apple\"] == 5;\n\nval m = Map.new_with_capacity(-5);\nm[\"pear\"] = 4;\nassert m[\"pear\"] == 4;\n"
  },
  {
    "path": "tests/map_frequency_map.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val fm1 = Map.frequency_map([\"apple\", \"banana\", \"apple\", \"orange\", \"banana\", \"apple\"]);\n    assert fm1[\"apple\"] == 3;\n    assert fm1[\"banana\"] == 2;\n    assert fm1[\"orange\"] == 1;\n    assert fm1.get(\"pear\").is_None();\n\n    val fm2 = Map.frequency_map([1, 2, 2, 3, 3, 3, 4]);\n    assert fm2[1] == 1;\n    assert fm2[2] == 2;\n    assert fm2[3] == 3;\n    assert fm2[4] == 1;\n    assert fm2.get(100).is_None();\n}\n"
  },
  {
    "path": "tests/map_hash_negative.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nstruct Foo {\n    type func new(x) = alloc(This) { .x };\n    func hash() {\n        return -1;\n    }\n    operator==(rhs: Foo) {\n        return this.x == rhs.x;\n    }\n}\n\nfunc main() {\n    val m = Map.new();\n    val f = Foo.new(42);\n    m[f] = \"The answer\";\n    assert m[f] == \"The answer\";\n}\n"
  },
  {
    "path": "tests/map_index_init.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new_with_capacity(5){\n        [123] = \"test\",\n        [456] = \"string\",\n        [false] = true,\n        [\"hello\"] = \"world\",\n    };\n\n    assert m[123] == \"test\";\n    assert m[456] == \"string\";\n    assert m[false] == true;\n    assert m[\"hello\"] == \"world\";\n}\n"
  },
  {
    "path": "tests/map_insert.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nval map = Map.new();\nassert map.set(1,2) == true;\nassert map.set(2,3) == true;\nassert map.set(1,4) == false;\n\nassert map[1] == 4;\nassert map[2] == 3;\n"
  },
  {
    "path": "tests/map_iter.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new() {\n        [1] = 2,\n        [2] = 3,\n        [3] = 4,\n        [4] = 5,\n        [5] = 6,\n        [6] = 7,\n    };\n\n    val key_total = 0;\n    for kvp in m {\n        assert kvp.value - kvp.key == 1;\n        key_total = key_total + kvp.key;\n    }\n\n    assert key_total == 21;\n}\n"
  },
  {
    "path": "tests/map_iterator_where.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new(){\n        [\"hello\"] = 123,\n        [\"A key\"] = true,\n        [\"Another key\"] = true,\n        [\"one more key\"] = 321,\n    };\n\n    val count = 0;\n    for item in m.iterator().where(|kvp| => kvp.key[0] == \"A\") {\n        assert item.value == true;\n        count = count + 1;\n    }\n\n    assert count == 2;\n}\n"
  },
  {
    "path": "tests/map_key_ops.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new();\n\n    m[123] = \"test\";\n    m[456] = \"string\";\n    m[false] = true;\n    m[\"hello\"] = \"world\";\n\n    assert m[123] == \"test\";\n    assert m[456] == \"string\";\n    assert m[false] == true;\n    assert m[\"hello\"] == \"world\";\n}\n"
  },
  {
    "path": "tests/map_keys.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new() {\n        [\"hello\"] = \"world\",\n        [\"test\"] = \"value\",\n        [\"123\"] = \"one hundred twenty three\",\n        [123] = 123,\n    };\n\n    val keys = m.keys();\n    assert keys.len() == 4;\n    assert keys.contains(\"hello\");\n    assert keys.contains(\"test\");\n    assert keys.contains(\"123\");\n    assert keys.contains(123);\n}\n"
  },
  {
    "path": "tests/map_load_factor.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new_with_capacity(5);\n\n    m[0] = 1;\n    m[1] = 2;\n    m[2] = 3;\n    m[3] = 4;\n    m[4] = 5;\n    m[5] = 6;\n    m[6] = 7;\n    m[7] = 8;\n    m[8] = 9;\n    m[9] = 10;\n    m[10] = 11;\n    m[11] = 12;\n    m[12] = 13;\n    m[13] = 14;\n    m[14] = 15;\n    m[15] = 16;\n    m[16] = 17;\n    m[17] = 18;\n    m[18] = 19;\n    m[19] = 20;\n\n    assert m.len() == 20;\n    for item in m {\n        assert item.value == item.key + 1;\n    }\n}\n"
  },
  {
    "path": "tests/map_remove.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new();\n    m.set(123, \"hello\");\n    m.set(456, \"world\");\n\n    assert m.get(123).is_Some();\n    assert m.get(456).is_Some();\n\n    assert m.len() == 2;\n\n    assert m.remove(123) == true;\n    assert m.remove(500) == false;\n\n    assert m.len() == 1;\n\n    assert m.get(123).is_None();\n    assert m.get(456).is_Some();\n\n    m.set(123, \"test string\");\n\n    assert m.len() == 2;\n\n    assert m.get(123).unwrap_Some() == \"test string\";\n    assert m.get(456).unwrap_Some() == \"world\";\n\n    assert m.remove(456) == true;\n    assert m.get(456).is_None();\n    assert m.remove(456) == false;\n}\n"
  },
  {
    "path": "tests/map_set_get.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Map from aria.structures.map;\n\nfunc main() {\n    val m = Map.new();\n    m.set(123, \"hello\");\n    m.set(\"hello\", \"world\");\n    m.set(false, true);\n    m.set(true, false);\n\n    assert m.get(123).unwrap_Some() == \"hello\";\n    assert m.get(\"hello\").unwrap_Some() == \"world\";\n\n    assert m.get(445566).is_None();\n    assert m.get(\"world\").is_None();\n}\n"
  },
  {
    "path": "tests/match_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc is_even_digit(x) {\n    match x {\n        == 0 => { return true; },\n        == 2 => { return true; },\n        == 4 => { return true; },\n        == 6 => { return true; },\n        == 8 => { return true; },\n    } else {\n        return false;\n    }\n}\n\nfunc main() {\n    assert is_even_digit(4);\n    assert !is_even_digit(7);\n}\n"
  },
  {
    "path": "tests/match_extract_enum_payload.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n# this should be a real enum\nenum Optional {\n    case Some(Any),\n    case None,\n}\n\nextension Optional {\n    instance func get_Some() {\n        match this {\n            case Some(x) => { return x; },\n        } else {\n            assert(false);\n        }\n    }\n}\n\nfunc main() {\n    val s = Optional::Some(123);\n\n    val n = s.get_Some();\n    assert n == 123;\n}\n"
  },
  {
    "path": "tests/match_isa_case.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum X {\n    case A,\n    case B(String),\n    case C(Int)\n}\n\n\nfunc main() {\n    val b = X::B(\"hello world\");\n    val str = \"goodbye\";\n    match b {\n        isa Int => { assert(false); },\n        isa X and case A => { assert(false); },\n        isa X and case B(s) => { str = s; },\n    } else {\n        assert(false);\n    }\n\n    assert str == \"hello world\";\n}\n"
  },
  {
    "path": "tests/match_not_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val check = false;\n\n    match 5 {\n        != 5 => { assert(false); },\n        == 4 => { assert false; },\n        != 4 => { check = true; },\n    } else {\n        assert false;\n    }\n\n    assert check;\n}\n"
  },
  {
    "path": "tests/match_payload_fails_with_no_payload.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Something {\n    case HasPayload(Any),\n    case HasNoPayload\n}\n\nfunc do_the_thing(x: Something) {\n    match x {\n        case HasPayload(x) => { return x; }\n    } else {\n        return 123456;\n    }\n}\n\nfunc main() {\n    val thing = do_the_thing(Something::HasNoPayload);\n    assert thing == 123456;\n\n    thing = do_the_thing(Something::HasPayload(\"hello\"));\n    assert thing == \"hello\";\n}\n"
  },
  {
    "path": "tests/match_rel.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 5;\n\n    val hit = false;\n\n    match x {\n        > 10 => {\n            assert false;\n        },\n        < 0 => {\n            assert false;\n        },\n        >= 6 => {\n            assert false;\n        },\n        <= 2 => {\n            assert false;\n        }\n        >= 3 => {\n            hit = true;\n        }\n    } else {\n        assert false;\n    }\n\n    assert hit;\n}\n"
  },
  {
    "path": "tests/match_uses_custom_op_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct EqualsFive {\n    operator ==(rhs) {\n        return rhs == 5;\n    }\n}\n\nfunc main() {\n    val f = alloc(EqualsFive);\n    val yes = false;\n\n    match f {\n        == 3 => { assert false; },\n        isa Int => { assert false; },\n        == 5 => { yes = true; },\n        case Foo => { assert false; },\n    } else {\n        assert false;\n    }\n\n    assert yes;\n}\n"
  },
  {
    "path": "tests/match_without_commas.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Foo {\n    case A\n    case B\n    case C\n    case D\n    case E\n}\n\nextension Foo {\n    func to_int() {\n        match this {\n            case A => {\n                return 1;\n            }\n            case B => {\n                return 2;\n            }\n            case C => {\n                return 3;\n            }\n            case D => {\n                return 4;\n            }\n            case E => {\n                return 5;\n            }\n        }\n    }\n}\n\nfunc main() {\n    val a = Foo::A;\n    val b = Foo::B;\n    val c = Foo::C;\n    val d = Foo::D;\n    val e = Foo::E;\n\n    assert a.to_int() == 1;\n    assert b.to_int() == 2;\n    assert c.to_int() == 3;\n    assert d.to_int() == 4;\n    assert e.to_int() == 5;\n}\n"
  },
  {
    "path": "tests/matrix.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Matrix from aria.numerics.matrix;\n\nfunc main() {\n    val m = Matrix.new(3, 3);\n    m.set(0, 0, 1.0f);\n    m.set(1, 1, 2.0f);\n    m[2,2] = 3.0f;\n    m.set(0, 1, 4.0f);\n    m[1,0] = 5.0f;\n\n    assert m.get(0, 0) == 1.0f;\n    assert m[1,1] == 2.0f;\n    assert m.get(2, 2) == 3.0f;\n    assert m[0,1] == 4.0f;\n    assert m.get(1, 0) == 5.0f;\n    assert m.get(0, 2) == 0.0f;\n\n    val caught = false;\n    try {\n        m.set(3, 3, 10.0f);\n    } catch e {\n        assert e isa Matrix.DimensionMismatch;\n        caught = true;\n    }\n    assert caught;\n\n    val caught = false;\n    try {\n        m.get(4, 6);\n    } catch e {\n        assert e isa Matrix.DimensionMismatch;\n        caught = true;\n    }\n    assert caught;\n}\n"
  },
  {
    "path": "tests/matrix_add.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Matrix from aria.numerics.matrix;\n\nfunc main() {\n    val m1 = Matrix.new(3,3);\n    m1.set(0, 0, 1.0f);\n    m1.set(1, 0, 0.25f);\n    m1.set(1, 1, 2.0f);\n    m1.set(2, 2, 3.0f);\n\n    val m2 = Matrix.new(3,3);\n    m2.set(0, 1, 4.0f);\n    m2.set(1, 0, 5);\n    m2.set(2, 2, 6);\n\n    val m3 = m1 + m2;\n\n    assert m3.get(0, 0) == 1.0f;\n    assert m3.get(1, 1) == 2.0f;\n    assert m3.get(2, 2) == 9.0f;\n    assert m3.get(0, 1) == 4.0f;\n    assert m3.get(1, 0) == 5.25f;\n    assert m3.get(0, 2) == 0.0f;\n    assert m3.get(2, 0) == 0.0f;\n\n    val m4 = m1 - m2;\n    assert m4.get(0, 0) == 1.0f;\n    assert m4.get(1, 1) == 2.0f;\n    assert m4.get(2, 2) == -3.0f;\n    assert m4.get(0, 1) == -4.0f;\n    assert m4.get(1, 0) == -4.75f;\n    assert m4.get(0, 2) == 0.0f;\n    assert m4.get(2, 0) == 0.0f;\n}\n"
  },
  {
    "path": "tests/matrix_det.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Matrix from aria.numerics.matrix;\n\nfunc main() {\n    val m = Matrix.new(3,3);\n\n    m[0,0] = 3;\n    m[0,1] = 3;\n    m[0,2] = 3;\n    m[1,0] = 4;\n    m[1,1] = 2;\n    m[1,2] = 5;\n    m[2,0] = 1;\n    m[2,1] = 6;\n    m[2,2] = 2;\n\n    assert m.determinant() == -21;\n\n    m = Matrix.new(10,10);\n    assert m.determinant() == 0;\n\n    m[0,0] = 5;\n    m[1,1] = 5;\n    m[2,2] = 5;\n    m[3,3] = 5;\n    m[4,4] = 5;\n    m[5,5] = 5;\n    m[6,6] = 5;\n    m[7,7] = 5;\n    m[8,8] = 5;\n    m[9,9] = 5;\n\n    assert m.determinant() == 9765625;\n}\n"
  },
  {
    "path": "tests/matrix_mul.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Matrix from aria.numerics.matrix;\n\nfunc main() {\n    val m1 = Matrix.new(2, 3);\n    m1.set(0, 0, 1);\n    m1.set(0, 1, 2);\n    m1.set(0, 2, 3);\n    m1.set(1, 0, 3);\n    m1.set(1, 1, 2);\n    m1.set(1, 2, 1);\n\n    val m2 = Matrix.new(3, 2);\n    m2.set(0, 0, 1);\n    m2.set(0, 1, 2);\n    m2.set(1, 0, 3);\n    m2.set(1, 1, 2);\n    m2.set(2, 0, 2);\n    m2.set(2, 1, 1);\n\n    val result = m1 * m2;\n    assert result.rows == 2;\n    assert result.cols == 2;\n\n    assert result.get(0, 0) == 13;\n    assert result.get(0, 1) == 9;\n    assert result.get(1, 0) == 11;\n    assert result.get(1, 1) == 11;\n}\n"
  },
  {
    "path": "tests/matrix_transpose.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Matrix from aria.numerics.matrix;\n\nfunc main() {\n    val m = Matrix.new(3,3);\n\n    m.set(0, 0, 1.0f);\n    m.set(1, 0, 2.0f);\n    m.set(1, 1, 3.0f);\n    m.set(1, 2, 6.0f);\n    m.set(2, 2, 4.0f);\n    m.set(0, 1, 5.0f);\n    m.set(2, 0, 7.0f);\n    m.set(0, 2, 8.0f);\n    m.set(2, 1, 9.0f);\n\n    val mt = m.transpose();\n    assert mt.get(0, 0) == m.get(0, 0);\n    assert mt.get(0, 1) == m.get(1, 0);\n    assert mt.get(0, 2) == m.get(2, 0);\n    assert mt.get(1, 0) == m.get(0, 1);\n    assert mt.get(1, 1) == m.get(1, 1);\n    assert mt.get(1, 2) == m.get(2, 1);\n    assert mt.get(2, 0) == m.get(0, 2);\n    assert mt.get(2, 1) == m.get(1, 2);\n    assert mt.get(2, 2) == m.get(2, 2);\n}\n"
  },
  {
    "path": "tests/max_min_empty.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.iterator.mixin;\n\nassert [].max().is_None();\nassert [].min().is_None();\n"
  },
  {
    "path": "tests/maybe_unwrap.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc calculate(x: Maybe) = Maybe::Some(x? + 1);\n\nassert calculate(Maybe::Some(1)) == Maybe::Some(2);\nassert calculate(Maybe::None) == Maybe::None;\n\nassert calculate(Maybe::Some(10))! == 11;\n"
  },
  {
    "path": "tests/method_arg_type_mismatch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Adder {\n    type func new(x) {\n        return alloc(Adder){.x = x,};\n    }\n\n    instance func add(x: Int) {\n        this.x + x;\n    }\n}\n\nfunc main() {\n    val caught = false;\n    val a = Adder.new(4);\n\n    try {\n        val n = a.add(false);\n        assert false;\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/method_as_arg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct AddNumber {\n    type func new(n) {\n        return alloc(This) {\n            .n = n,\n        };\n    }\n\n    func add(x) {\n        return this.n + x;\n    }\n}\n\nfunc perform_op(f,n) {\n    return f(n);\n}\n\nfunc main() {\n    val add5 = AddNumber.new(5);\n    assert perform_op(add5.add,4) == 9;\n}\n"
  },
  {
    "path": "tests/method_has_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct TakesVarArgs {\n    type func new(){\n        return alloc(This){\n            .value = 0,\n        };\n    }\n\n    func add_at_least_one(n, ...) {\n        this.value += n;\n        for arg in varargs {\n            this.value += arg;\n        }\n    }\n\n    func add_any_count(...) {\n        for arg in varargs {\n            this.value += arg;\n        }\n    }\n\n    func add_at_least_two(x,y, ...) {\n        this.value += x+y;\n        for arg in varargs {\n            this.value += arg;\n        }\n    }\n}\n\nfunc main() {\n    val va = TakesVarArgs.new();\n\n    va.add_at_least_one(3);\n    assert va.value == 3;\n    va.add_at_least_one(3,4,5);\n    assert va.value == 15;\n    va.add_at_least_one(5,2);\n    assert va.value == 22;\n\n    va.add_any_count();\n    assert va.value == 22;\n    va.add_any_count(1);\n    assert va.value == 23;\n    va.add_any_count(3,1,1,2);\n    assert va.value == 30;\n\n    va.add_at_least_two(3,4);\n    assert va.value == 37;\n    va.add_at_least_two(3,5,4);\n    assert va.value == 49;\n    va.add_at_least_two(1,5,4,1,9,1);\n    assert va.value == 70;\n}\n"
  },
  {
    "path": "tests/method_on_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new(x,y,z) {\n        val f = alloc(This);\n        return f.set(x,y,z);\n    }\n\n    instance func set(x,y,z) {\n        this.x = x;\n        this.y = y;\n        this.z = (x+y==z);\n        return this;\n    }\n}\n\nfunc main() {\n    val f = Foo.new(1,2,4);\n    assert f.x == 1;\n    assert f.y == 2;\n    assert f.z == false;\n\n    f.set(2,3,5);\n    assert f.x == 2;\n    assert f.y == 3;\n    assert f.z == true;\n}\n"
  },
  {
    "path": "tests/method_order_of_vararg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct TakesVarArgs {\n    func compare(l,...) {\n        assert this isa TakesVarArgs;\n\n        assert l == varargs;\n    }\n}\n\nfunc main() {\n    val va = alloc(TakesVarArgs);\n\n    va.compare([3],3);\n    va.compare([3,4],3,4);\n    va.compare([3,4,5,6],3,4,5,6);\n    va.compare([]);\n}\n"
  },
  {
    "path": "tests/mismatch_payload.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    try {\n        val some = Maybe::Some;\n    } catch e {\n        assert e isa RuntimeError;\n        assert e.is_UnexpectedType();\n    }\n\n    try {\n        val none = Maybe::None(3);\n    } catch e {\n        assert e isa RuntimeError;\n        assert e.is_UnexpectedType();\n    }\n}\n"
  },
  {
    "path": "tests/mix_int_fp_mod.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert 2.5f % 1 == 0.5f;\n    assert 2 % 1.0f == 0.0f;\n}\n"
  },
  {
    "path": "tests/mix_object_init.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 42;\n\nval l = [] {\n    [0] = 1,\n    [1] = 2,\n    .foo = \"bar\",\n    .bar = \"hello\",\n    [2] = 3,\n    .x,\n    [3] = 4,\n};\n\nassert l[0] == 1;\nassert l[1] == 2;\nassert l.foo == \"bar\";\nassert l.bar == \"hello\";\nassert l[2] == 3;\nassert l[3] == 4;\nassert l.x == 42;\n"
  },
  {
    "path": "tests/mixin_extension.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Foo {\n    func bar() {\n        return 1;\n    }\n}\n\nstruct UsesFoo {\n    include Foo\n}\n\nextension Foo {\n    func baz() {\n        return 2;\n    }\n}\n\nmixin Bar {\n    func double() {\n        return this * 2;\n    }\n}\n\nextension Int : Bar {\n}\n\nfunc test_extension_shorthand() {\n    assert 5.double() == 10;\n}\n\nfunc main() {\n    val f = alloc(UsesFoo);\n    assert f.bar() == 1;\n\n    assert f.baz() == 2;\n    test_extension_shorthand();\n}\n"
  },
  {
    "path": "tests/mixin_func_This.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct S1 {\n    type func new(x) {\n        return alloc(This) {\n            .x = x + 1,\n        };\n    }\n}\n\nstruct S2 {\n    type func new(x) {\n        return alloc(This) {\n            .x = x + 2,\n        };\n    }\n}\n\nmixin DoubleMe {\n    func double() {\n        val This = typeof(this);\n        return This.new(this.x * 2);\n    }\n}\n\nextension S1 {\n    include DoubleMe\n}\n\nextension S2 {\n    include DoubleMe\n}\n\nfunc main() {\n    val s1 = S1.new(5);\n    val s2 = S2.new(6);\n\n    assert s1.x == 6;\n    assert s2.x == 8;\n\n    val ds1 = s1.double();\n    assert ds1.x == 13;\n    assert ds1 isa S1;\n\n    val ds2 = s2.double();\n    assert ds2.x == 18;\n    assert ds2 isa S2;\n}"
  },
  {
    "path": "tests/mixin_has_enum.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Foo {\n    struct Pair {\n        type func new(x,y) = alloc(This) {.x, .y} ;\n    }\n\n    enum Either {\n        case Left(Foo.Pair),\n        case Right(Any),\n    }\n}\n\nstruct S1 {\n    include Foo\n}\n\nfunc main() {\n    val either_left = S1.Either::Left(S1.Pair.new(2,3));\n    val either_right = S1.Either::Right(\"hello\");\n\n    assert either_left.is_Left();\n    assert either_right.is_Right();\n\n    assert either_left.unwrap_Left().x == 2;\n    assert either_left.unwrap_Left().y == 3;\n\n    assert either_right.unwrap_Right() == \"hello\";\n}\n"
  },
  {
    "path": "tests/mixin_has_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Foo {\n    struct Bar {\n        type func new(x) = alloc(This) {.x} ;\n\n        func add(y) = this.x + y;\n    }\n}\n\nstruct S1 {\n    include Foo\n}\n\nstruct S2 {\n    include Foo\n}\n\nfunc main() {\n    val s1_bar = S1.Bar.new(2);\n    val s2_bar = S2.Bar.new(3);\n\n    assert s1_bar isa S2.Bar;\n    assert s2_bar isa S1.Bar;\n\n    assert s1_bar.add(3) == 5;\n    assert s2_bar.add(3) == 6;\n}\n"
  },
  {
    "path": "tests/mixin_in_extension.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nmixin Double {\n    # requires\n    # this.value()\n    # this.add(y)\n    func double() {\n        return this.add(this.value());\n    }\n}\n\nstruct HasValue {\n    type func new(x) {\n        return alloc(This) {\n            .x = x,\n        };\n    }\n}\n\nextension HasValue {\n    instance func value() {\n        return this.x;\n    }\n\n    instance func add(y) {\n        this.x += y;\n    }\n\n    include Double\n}\n\nfunc main() {\n    val hv = HasValue.new(4);\n\n    assert hv.value() == 4;\n    hv.add(1);\n    assert hv.value() == 5;\n    hv.double();\n    assert hv.value() == 10;\n    hv.double();\n    assert hv.value() == 20;\n    hv.add(3);\n    assert hv.value() == 23;\n}\n\n"
  },
  {
    "path": "tests/mixin_include_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Double {\n    func double(n) {\n        return n + n;\n    }\n}\n\nmixin Triple {\n    func triple(n) {\n        return this.double(n) + n;\n    }\n\n    include Double\n}\n\nstruct Test {\n    include Triple\n}\n\nfunc main() {\n    val t = alloc(Test);\n\n    assert t.double(2) == 4;\n    assert t.triple(4) == 12;\n}\n"
  },
  {
    "path": "tests/mixin_include_type_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin HasTypeFunc {\n    # requires\n    # type func new_with_pair(x,y)\n    type func new_with_duplicate(x) {\n        return This.new_with_pair(x,x);\n    }\n}\n\nstruct TestStruct {\n    type func new_with_pair(x,y) {\n        return alloc(This){\n            .x = x,\n            .y = y,\n        };\n    }\n\n    include HasTypeFunc\n}\n\nfunc main() {\n    val t = TestStruct.new_with_duplicate(5);\n    assert t.x == 5;\n    assert t.y == 5;\n}\n\n"
  },
  {
    "path": "tests/mixin_multiple_commas.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nmixin A {\n    func from_a() {\n        return \"A\";\n    }\n}\n\nmixin B {\n    func from_b() {\n        return \"B\";\n    }\n}\n\nmixin C {\n    func from_c() {\n        return \"C\";\n    }\n}\n\n# Test trailing comma with single mixin\nstruct Single : A, {\n    type func new() {\n        return alloc(This);\n    }\n}\n\n# Test trailing comma with multiple mixins\nstruct Multi : A, B, C, {\n    type func new() {\n        return alloc(This);\n    }\n}\n\n# Test no trailing comma still works\nstruct NoTrailing : A, B {\n    type func new() {\n        return alloc(This);\n    }\n}\n\n# Test extension with trailing comma\nextension Int : A, B, {\n}\n\nfunc main() {\n    val s = Single.new();\n    assert s.from_a() == \"A\";\n    \n    val m = Multi.new();\n    assert m.from_a() == \"A\";\n    assert m.from_b() == \"B\";\n    assert m.from_c() == \"C\";\n    \n    val n = NoTrailing.new();\n    assert n.from_a() == \"A\";\n    assert n.from_b() == \"B\";\n    \n    assert 5.from_a() == \"A\";\n    assert 5.from_b() == \"B\";\n}"
  },
  {
    "path": "tests/mixin_of_builtin_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin Double {\n    func double() {\n        return this + this;\n    }\n}\n\nextension Int {\n    include Double\n}\n\nextension String {\n    include Double\n}\n\nextension Float {\n    include Double\n}\n\nextension Double {\n    func triple() {\n        return this + this + this;\n    }\n}\n\nfunc main() {\n    assert 3.double() == 6;\n    assert \"abc\".double() == \"abcabc\";\n    assert 3.14f.double() == 6.28f;\n\n    assert 3.triple() == 9;\n    assert \"abc\".triple() == \"abcabcabc\";\n    assert 3.14f.triple() == 9.42f;\n}\n"
  },
  {
    "path": "tests/mixin_of_enum.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Direction {\n    case North,\n    case South,\n    case East,\n    case West,\n}\n\nextension Direction {\n    func prettyprint() {\n        match this {\n            case North => { return \"North\"; },\n            case South => { return \"South\"; },\n            case East => { return \"East\"; },\n            case West => { return \"West\"; },\n        }\n    }\n}\n\nmixin Navigation {\n    func navigate() {\n        return \"Head {0}\".format(this);\n    }\n}\n\nextension Direction : Navigation {\n}\n\nfunc main() {\n    val d = Direction::East;\n\n    assert d.navigate() == \"Head East\";\n}\n"
  },
  {
    "path": "tests/mixin_order.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin A {\n    func answer() {\n        return \"Mixin A\";\n    }\n}\n\nmixin B {\n    func answer() {\n        return \"Mixin B\";\n    }\n}\n\nstruct A_Then_B {\n    include A\n    include B\n}\n\nstruct B_Then_A {\n    include B\n    include A\n}\n\nstruct C_Shorthand_Then_B : A {\n    include B\n}\n\nfunc test_shorthand_order() {\n    val c = alloc(C_Shorthand_Then_B);\n    assert c.answer() == \"Mixin B\";  # should be B (last included)\n}\n\nfunc main() {\n    val a_then_b = alloc(A_Then_B);\n    val b_then_a = alloc(B_Then_A);\n\n    assert a_then_b.answer() == \"Mixin B\";\n    assert b_then_a.answer() == \"Mixin A\"; \n    test_shorthand_order();\n}\n"
  },
  {
    "path": "tests/mixin_refers_to_self_method.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nmixin Double {\n    # requires\n    # this.value()\n    # this.add(y)\n    func double() {\n        return this.add(this.value());\n    }\n}\n\nstruct HasValue {\n    type func new(x) {\n        return alloc(This) {\n            .x = x,\n        };\n    }\n\n    instance func value() {\n        return this.x;\n    }\n\n    instance func add(y) {\n        this.x += y;\n    }\n\n    include Double\n}\n\nfunc main() {\n    val hv = HasValue.new(4);\n\n    assert hv.value() == 4;\n    hv.add(1);\n    assert hv.value() == 5;\n    hv.double();\n    assert hv.value() == 10;\n    hv.double();\n    assert hv.value() == 20;\n    hv.add(3);\n    assert hv.value() == 23;\n}\n\n"
  },
  {
    "path": "tests/mixin_shared_between_types.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin SomeBehavior {\n    # requires\n    # func input()\n    func behavior() {\n        return \"input is {0}\".format(this.input());\n    }\n}\n\nstruct ProvidesInteger {\n    func input() {\n        return 42;\n    }\n}\n\nstruct ProvidesString {\n    func input() {\n        return \"hello\";\n    }\n}\n\nextension ProvidesInteger : SomeBehavior {\n}\n\nextension ProvidesString : SomeBehavior {\n}\n\nfunc main() {\n    val pib = alloc(ProvidesInteger).behavior();\n    val psb = alloc(ProvidesString).behavior();\n\n    assert pib == \"input is 42\";\n    assert psb == \"input is hello\";\n}\n"
  },
  {
    "path": "tests/mixin_val_decl.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin HasSomeValue {\n    func get_foo() {\n        return this.FOO;\n    }\n\n    type val FOO = 1;\n}\n\nstruct S1 {\n    include HasSomeValue\n}\n\nstruct S2 {\n    include HasSomeValue\n}\n\nfunc main() {\n    assert S1.FOO == 1;\n    assert S2.FOO == 1;\n    assert alloc(S1).get_foo() == 1;\n    assert alloc(S2).get_foo() == 1;\n\n    S1.FOO = 2;\n    assert S1.FOO == 2;\n    assert S2.FOO == 1;\n    assert alloc(S1).get_foo() == 2;\n    assert alloc(S2).get_foo() == 1;\n\n    S2.FOO = 3;\n    assert S1.FOO == 2;\n    assert S2.FOO == 3;\n    assert alloc(S1).get_foo() == 2;\n    assert alloc(S2).get_foo() == 3;\n}\n"
  },
  {
    "path": "tests/mod_by_zero.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc test_mod(x,y) {\n    try {\n        val n = x % y;\n        assert false; # should not reach here\n    } catch e {\n        return e isa RuntimeError && e.is_DivisionByZero();\n    }\n}\n\nassert test_mod(3, 0);\nassert test_mod(3, 0.0f);\nassert test_mod(3.0f, 0);\nassert test_mod(3.0f, 0.0f);\n\nassert test_mod(0, 0);\nassert test_mod(0, 0.0f);\nassert test_mod(0.0f, 0);\nassert test_mod(0.0f, 0.0f);\n"
  },
  {
    "path": "tests/module_level_val.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval foo = 123;\n\nfunc bar() {\n    foo = 321;\n}\n\nfunc baq(foo) {\n    foo = 4;\n}\n\nfunc main() {\n    assert foo == 123;\n    bar();\n    assert foo == 321;\n    baq(5);\n    assert foo == 321;\n}\n"
  },
  {
    "path": "tests/module_level_var_fdeps.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(n) {\n    return 5+n;\n}\n\nval ten = foo(5);\n\nfunc main() {\n    assert ten == 10;\n}\n"
  },
  {
    "path": "tests/module_list_attributes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport attributes.things;\n\nfunc main() {\n    val m_attribs = listattrs(attributes.things);\n    assert m_attribs.contains(\"foo\");\n    assert m_attribs.contains(\"Bar\");\n    assert m_attribs.contains(\"A\");\n    assert m_attribs.contains(\"Something\");\n    assert m_attribs.len() >= 4;\n}\n"
  },
  {
    "path": "tests/module_var_isa_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin A {\n    func answer() {\n        return 42;\n    }\n}\n\nstruct S {\n    include A\n}\n\nval x: A = alloc(S);\n\nfunc main() {\n    assert x.answer() == 42;\n}\n"
  },
  {
    "path": "tests/msrng.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport MiddleSquareRng from aria.rng.msws;\nimport aria.iterator.mixin;\n\nfunc is_within_range(n) {\n    return (n >= 1) && (n <= 6);\n}\n\nfunc main() {\n    val rng = MiddleSquareRng.new();\n\n    # TODO: replace this with a proper verification, this is not exactly\n    # guaranteed - just very very likely\n    assert rng.next() != rng.next();\n    assert rng.next() != rng.next();\n    assert rng.next() != rng.next();\n\n    val n = 0;\n    val l = [];\n    while n < 100 {\n        n = n + 1;\n        l.append(rng.in_range(1,6));\n    }\n\n    assert l.iterator().all(is_within_range);\n}\n"
  },
  {
    "path": "tests/mul_eq_ops.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 3;\n    \n    x *= 4;\n    assert x == 12;\n\n    x /= 2;\n    assert x == 6;\n\n    x %= 4;\n    assert x == 2;\n\n    x <<= 3;  # 2 << 3 = 16\n    assert x == 16;\n\n    x >>= 2;  # 16 >> 2 = 4\n    assert x == 4;\n}"
  },
  {
    "path": "tests/multidecl_order.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1, y = x + 1, z = Box(){.x,.y};\n\nassert x == 1;\nassert y == 2;\nassert z.x == 1;\nassert z.y == 2;\n\nval i = 0, a = []{[i] = 1, [i+1] = x};\nassert a == [1,1];"
  },
  {
    "path": "tests/multiple_imports_from.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport one, two from multiple.module;\n\nfunc main() {\n    assert one(3,4) == 7;\n    assert two(3,4) == 12;\n}\n"
  },
  {
    "path": "tests/multiwrite_multiple.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1, y = 2, z = 3, t = 4, q = 5, p = 6;\n\nx,y,z = 10,20,30;\nt,q,p = 40,50,60;\n\nassert x == 10;\nassert y == 20;\nassert z == 30;\n\nassert t == 40;\nassert q == 50;\nassert p == 60;\n\nx,y,z,t,q,p = 100,200,300,400,500,600;\n\nassert x == 100;\nassert y == 200;\nassert z == 300;\nassert t == 400;\nassert q == 500;\nassert p == 600;\n\nx,y,z = z,x,y;\n\nassert x == 300;\nassert y == 100;\nassert z == 200;\n"
  },
  {
    "path": "tests/multiwrite_nesting.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval a = Box();\na.x = [Box()];\nval b = [1, 2, 3, 4];\n\nfunc z() = 1;\nfunc p() = 42;\nfunc q() = 99;\n\na.x[0].y, b[z()] = p(), q();\n\nassert a.x[0].y == 42;\nassert b[1] == 99;\n"
  },
  {
    "path": "tests/multiwrite_of_attribute.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval b = Box();\n\nb.x, b.y = 3, 4;\nassert b.x == 3;\nassert b.y == 4;\n\nb.x, b.y = b.y, b.x;\nassert b.x == 4;\nassert b.y == 3;\n"
  },
  {
    "path": "tests/multiwrite_repeat.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1;\n\nx,x = 3,4;\n\nassert x == 4;\n"
  },
  {
    "path": "tests/multiwrite_side_effecting.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval i = 0, a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\nfunc f() = 42;\n\na[i], i = f(), 7;\n\nassert a[0] == 42;\nassert i == 7;\n\ni, a[i] = 6, f();\n\nassert a[6] == 42;\nassert i == 6;\n"
  },
  {
    "path": "tests/multiwrite_swap.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1, y = 2;\n\nx,y = y,x;\n\nassert x == 2;\nassert y == 1;\n"
  },
  {
    "path": "tests/naked_return.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc returns_unit(x: Bool, y: Any) {\n    if x {\n        return y;\n    } else {\n        return;\n    }\n\n    assert false; # this should never be reached\n}\n\nfunc returns_fallthrough(x: Bool, y: Any) {\n    if x {\n        return y;\n    }\n}\n\nfunc main() {\n    val five = returns_unit(true, 5);\n    val unit = returns_unit(false, 5);\n\n    assert five == 5;\n    assert unit == Unit::unit;\n\n    val five_again = returns_fallthrough(true, 5);\n    val unit_again = returns_fallthrough(false, 5);\n\n    assert five_again == 5;\n    assert unit_again == Unit::unit;\n}\n"
  },
  {
    "path": "tests/neg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = -3;\n    val y = 3;\n    assert x < 0;\n    assert y > 0;\n    assert y > x;\n    assert x < y;\n    assert (x+y == 0);\n    assert x != 0;\n    assert y != 0;\n    assert y-x == 6;\n}\n"
  },
  {
    "path": "tests/nested_closure.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc top_level(arg0) {\n    return |arg1| => |arg2| => arg0 + arg1 + arg2;\n}\n\nfunc main() {\n    val add3 = top_level(3);\n\n    val add3_and_4 = add3(4);\n    val add3_and_2 = add3(2);\n\n    assert add3_and_4(7) == 14;\n    assert add3_and_2(7) == 12;\n\n    assert add3_and_4(3) == 10;\n    assert add3_and_2(1) == 6;\n}\n"
  },
  {
    "path": "tests/nested_enum_in_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc parity(x) {\n    enum Parity {\n        case Even,\n        case Odd,\n    }\n\n    if (x % 2 == 0) {\n        return Parity::Even;\n    } else {\n        return Parity::Odd;\n    }\n}\n\nfunc main() {\n    val p3 = parity(3);\n    val p6 = parity(6);\n\n    assert p3.is_Odd();\n    assert !p3.is_Even();\n\n    assert p6.is_Even();\n    assert !p6.is_Odd();\n\n    val hit = false;\n    match p6 {\n        case Even => {\n            hit = true;\n        }\n    }\n    assert hit;\n\n    val hit = false;\n    match p3 {\n        case Odd => {\n            hit = true;\n        }\n    }\n    assert hit;\n}\n"
  },
  {
    "path": "tests/nested_enum_with_entries.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct A {\n    enum B {\n        case X\n        func foo() {\n            return 42;\n        }\n    }\n\n    func b() {\n        return A.B::X.foo();\n    }\n\n    type func c() {\n        return alloc(This).b();\n    }\n}\n\nfunc main() {\n    assert A.c() == 42;\n    assert alloc(A).b() == 42;\n    assert A.B::X.foo() == 42;\n}\n"
  },
  {
    "path": "tests/nested_extension.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport base_module.nested_module.content;\n\nextension base_module.nested_module.content.Foo {\n    type func new(x) {\n        return alloc(This) {\n            .x = x,\n        };\n    }\n\n    func increment() {\n        this.x += 1;\n    }\n\n    func answer_x() {\n        return this.answer() + this.x;\n    }\n}\n\nfunc main() {\n    val f = base_module.nested_module.content.Foo.new(1);\n    f.increment();\n\n    assert f.answer() == 42;\n    assert f.answer_x() == 44;\n}\n"
  },
  {
    "path": "tests/nested_forloop.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val l = [1,2,3,4,5];\n    val total_loops = 0;\n    \n    val a_sum = 0;\n    for a in l {\n        total_loops = total_loops + 1;\n        val b_sum = 0;\n        for b in l {\n            total_loops = total_loops + 1;\n            b_sum = b_sum + b;\n        }\n        assert b_sum == 15;\n        a_sum = a_sum + a;\n    }\n    assert a_sum == 15;\n    assert total_loops == 30; # 5x outer loop + 5 times 5x inner loop\n}\n"
  },
  {
    "path": "tests/nested_guard.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct Guard {\n    type val COUNTER = 0;\n\n    instance func guard_exit() {\n        Guard.COUNTER = Guard.COUNTER + 1;\n    }\n}\n\nfunc main() {\n    val n = guard(alloc(Guard)).do(|x| => {\n        val n = guard(alloc(Guard)).do(|y| => {\n            return 1;\n        })?;\n\n        assert Guard.COUNTER == 1;\n        return n + 1;\n    })?;\n\n    assert n == 2;\n    assert Guard.COUNTER == 2;\n}\n"
  },
  {
    "path": "tests/nested_guards_order.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct GuardOne {\n    type val COUNTER = 1;\n\n    func guard_exit() {\n        GuardOne.COUNTER = GuardOne.COUNTER + GuardTwo.COUNTER;\n    }\n}\n\nstruct GuardTwo {\n    type val COUNTER = 2;\n\n    func guard_exit() {\n        GuardTwo.COUNTER = GuardTwo.COUNTER + GuardOne.COUNTER;\n    }\n}\n\nfunc add(x,y) {\n    return guard(alloc(GuardOne)).do(|_| => {\n        return guard(alloc(GuardTwo)).do(|_| => {\n            return x + y;\n        });\n    });\n}\n\nfunc add_again(x,y) {\n    return guard(alloc(GuardTwo)).do(|_| => {\n        return guard(alloc(GuardOne)).do(|_| => {\n            return x + y;\n        });\n    });\n}\n\nfunc main() {\n    val n = add(3,4);\n    assert n == 7;\n    assert GuardTwo.COUNTER == 3;\n    assert GuardOne.COUNTER == 4;\n\n    GuardOne.COUNTER = 1;\n    GuardTwo.COUNTER = 2;\n\n    n = add_again(3,4);\n    assert n == 7;\n    assert GuardOne.COUNTER == 3;\n    assert GuardTwo.COUNTER == 5;\n}\n"
  },
  {
    "path": "tests/nested_if.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc do_compare(x,a,y,b) {\n    if x == a {\n        if y == b {\n            return 123;\n        } elsif y == a {\n            return 124;\n        } else {\n            return 125;\n        }\n    } elsif x == b {\n        if y == a {\n            return 321;\n        } elsif y == b {\n            return 324;\n        } else {\n            return 325;\n        }\n    }\n}\n\nfunc main() {\n    assert do_compare(3,3,4,3) == 125;\n\n    assert do_compare(3,3,4,4) == 123;\n\n    assert do_compare(5,0,0,5) == 321;\n\n    assert do_compare(2,1,2,2) == 324;\n}\n"
  },
  {
    "path": "tests/nested_lambda_f.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc top_level(q) {\n    # this is not a closure as nothing in any of the inner\n    # lexical scopes depends on anything in the outer scopes\n    return |a| => {\n        return |x,y| => x + y;\n    };\n}\n\nfunc main() {\n    val c1 = top_level(3);\n    val c2 = c1(4);\n    assert c2(3,4) == 7;\n}\n"
  },
  {
    "path": "tests/nested_list.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val list = [[1,2,3],[4,5,6]];\n\n    val one = list[0][0];\n    val three = list[0][2];\n    val five = list[1][1];\n    \n    val total = one + three + five;\n    assert total == 9;\n}"
  },
  {
    "path": "tests/nested_obj_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Pair {\n    type func new(x,y) = alloc(This){.x, .y};\n}\n\nstruct Quartet {\n    type func new(a,y,x,d) = alloc(This) {\n        .a = alloc(Pair) {\n            .x = a,\n            .y,\n        },\n        .c = alloc(Pair) {\n            .x,\n            .y = d\n        }\n    };\n}\n\nfunc main() {\n    val q = Quartet.new(1,2,3,4);\n\n    assert q.a.x == 1;\n    assert q.a.y == 2;\n    assert q.c.x == 3;\n    assert q.c.y == 4;\n}\n"
  },
  {
    "path": "tests/nested_struct_new.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Top {\n    struct Child {\n        enum E {\n            case A,\n            case B,\n        }\n\n        type func foo() {\n            return 42;\n        }\n    }\n}\n\nfunc main() {\n    assert Top.Child.foo() == 42;\n\n    assert Top.Child.E::A.is_A();\n}\n"
  },
  {
    "path": "tests/new_path.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\n\nfunc main() {\n    val p = Path.new(\"/usr/\");\n\n    val q = p / \"lib/libc.so\";\n    p /= \"bin/ls\";\n\n    assert p.prettyprint() == \"/usr/bin/ls\";\n    assert q.prettyprint() == \"/usr/lib/libc.so\";\n\n    p.pop();\n    assert p.prettyprint() == \"/usr/bin\";\n\n    assert p.parent().prettyprint() == \"/usr\";\n\n    p.pop();\n    assert p.prettyprint() == \"/usr\";\n\n    p.pop();\n    assert p.prettyprint() == \"/\";\n\n    p.pop();\n    assert p.prettyprint() == \"/\";\n\n    val cwd = Path.new_with_current_directory();\n    assert cwd.is_absolute();\n    assert cwd.exists();\n    assert cwd.is_directory();\n}\n"
  },
  {
    "path": "tests/new_range_api.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nfunc increasing_exclusive_range() {\n    val r = Range.from(1).to(10);\n    val items = r.iterator().to_list();\n    assert items == [1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n    assert r.contains(1) == true;\n    assert r.contains(10) == false;\n    assert r.length() == 9;\n}\n\nfunc increasing_inclusive_range() {\n    val r = Range.from(1).through(10);\n    val items = r.iterator().to_list();\n    assert items == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n    assert r.contains(1) == true;\n    assert r.contains(10) == true;\n    assert r.contains(11) == false;\n    assert r.length() == 10;\n}\n\nfunc decreasing_exclusive_range() {\n    val r = Range.from(1).to(10);\n    val items = r.descending().to_list();\n    assert items == [9, 8, 7, 6, 5, 4, 3, 2, 1];\n}\n\nfunc decreasing_inclusive_range() {\n    val r = Range.from(1).through(10);\n    val items = r.descending().to_list();\n    assert items == [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];\n}\n\nfunc increasing_exclusive_range_with_step() {\n    val r = Range.from(1).to(11).step(2);\n    val items = r.iterator().to_list();\n    assert items == [1, 3, 5, 7, 9];\n\n    val r = Range.from(1).to(10).step(2);\n    val items = r.iterator().to_list();\n    assert items == [1, 3, 5, 7, 9];\n}\n\nfunc increasing_inclusive_range_with_step() {\n    val r = Range.from(1).through(11).step(2);\n    val items = r.iterator().to_list();\n    assert items == [1, 3, 5, 7, 9, 11];\n\n    val r = Range.from(1).through(10).step(2);\n    val items = r.iterator().to_list();\n    assert items == [1, 3, 5, 7, 9];\n}\n\nfunc decreasing_exclusive_range_with_step() {\n    val r = Range.from(0).to(10);\n    val items = r.step(-2).to_list();\n    assert items == [9, 7, 5, 3, 1];\n\n    val r = Range.from(1).to(10);\n    val items = r.step(-2).to_list();\n    assert items == [9, 7, 5, 3, 1];\n}\n\nfunc decreasing_inclusive_range_with_step() {\n    val r = Range.from(0).through(10);\n    val items = r.step(-2).to_list();\n    assert items == [10, 8, 6, 4, 2, 0];\n\n    val r = Range.from(1).through(10);\n    val items = r.step(-2).to_list();\n    assert items == [10, 8, 6, 4, 2];\n}\n\nfunc union() {\n    val r1 = Range.from(1).to(5);\n    val r2 = Range.from(3).to(7);\n    val r3 = r1.union(r2);\n    assert r3.from == 1;\n    assert r3.to == 7;\n\n    val items = r3.iterator().to_list();\n    assert items == [1, 2, 3, 4, 5, 6];\n}\n\nfunc intersection() {\n    val r1 = Range.from(1).to(5);\n    val r2 = Range.from(3).to(7);\n    val r3 = r1.intersection(r2);\n    assert r3.from == 3;\n    assert r3.to == 5;\n\n    val items = r3.iterator().to_list();\n    assert items == [3, 4];\n}\n\nfunc main() {\n    increasing_exclusive_range();\n    increasing_inclusive_range();\n    decreasing_exclusive_range();\n    decreasing_inclusive_range();\n    increasing_exclusive_range_with_step();\n    increasing_inclusive_range_with_step();\n    decreasing_exclusive_range_with_step();\n    decreasing_inclusive_range_with_step();\n\n    union();\n    intersection();\n}\n"
  },
  {
    "path": "tests/no_such_case.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum E {\n    case A, case B,\n}\n\nfunc main() {\n    val caught = false;\n\n    try {\n        val foo = E::X;\n    } catch e {\n        match e {\n            isa RuntimeError and case NoSuchCase(n) => {\n                caught = n == \"X\";\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/no_such_identifier.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val caught = false;\n\n    try {\n        val foo = value + 1;\n    } catch e {\n        match e {\n            isa RuntimeError and case NoSuchIdentifier(n) => {\n                caught = n == \"value\";\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/not.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert !false;\n    assert !(!true);\n\n    assert !false == true;\n    assert !true == false;\n}\n"
  },
  {
    "path": "tests/nothing_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val v = Nothing;\n}\n"
  },
  {
    "path": "tests/now.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    # assume the clock is moving reasonably\n    # and that time travel does not exist\n    val n = now();\n    assert n > 0;\n    val mpy = 1000 * 60 * 60 * 24 * 365;\n    assert n/mpy >= 55;\n    assert now() >= n;\n}"
  },
  {
    "path": "tests/obj_box_read_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc make_pair(x,y) {\n    val pair = Box();\n    pair.x = x;\n    pair.y = y;\n    return pair;\n}\n\nfunc symmetrical(p) {\n    return make_pair(p.y, p.x);\n}\n\nfunc main() {\n    val p = make_pair(4,5);\n    assert p.x == 4;\n    assert p.y == 5;\n    \n    val q = symmetrical(p);\n    assert q.x == 5;\n    assert q.y == 4;\n}\n"
  },
  {
    "path": "tests/obj_prettyprint.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Pair {\n    type func new(x,y) {\n        return alloc(This) {\n            .x = x,\n            .y = y,\n        };\n    }\n\n    instance func prettyprint() {\n        return \"Pair({0},{1})\".format(this.x, this.y);\n    }\n}\n\nfunc main() {\n    val p = Pair.new(3,4);\n    val s = \"I am a pair and my values are {0}\".format(p);\n    assert s == \"I am a pair and my values are Pair(3,4)\";\n}\n"
  },
  {
    "path": "tests/obj_write_comprehensive.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval t = [];\nfunc rec(i) { t.append(i); return i; }\nval o = [] { [rec(0)] = rec(1), [rec(1)] = rec(2) };\nassert t == [0,1,1,2];\n"
  },
  {
    "path": "tests/obj_write_in_expr.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval s = \"x\"{.hello = \"world\"}.hello;\nassert s == \"world\";\n"
  },
  {
    "path": "tests/obj_write_order.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval o = Box() {\n    .a = 1,\n    .a = 2,\n    .a = 3,\n};\n\nassert o.a == 3;\n\nval p = [] {\n    [0] = 1,\n    [0] = 2,\n    [0] = 3\n};\n\nassert p[0] == 3;\n"
  },
  {
    "path": "tests/one_guard.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct Guard {\n    type val COUNTER = 0;\n\n    instance func guard_exit() {\n        Guard.COUNTER = Guard.COUNTER + 1;\n    }\n}\n\nfunc main() {\n    val n = guard(alloc(Guard)).do(|x| => {\n        return 1;\n    })!;\n\n    assert n == 1;\n    assert Guard.COUNTER == 1;\n}\n"
  },
  {
    "path": "tests/one_line_function.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc sum(x, y) = x + y;\nfunc assign() = 42;\n\nstruct TestStruct {\n    type func new(x) {\n        return alloc(This) {\n            .x = x\n        };\n    }\n\n    func get_x() = this.x;\n    func add_to_x(n) = this.x + n;\n    func multiply_x(n) = this.x * n;\n\n    operator + (other) = this.x + other.x;\n}\n\nfunc main() {\n    assert 5 == sum(3,2);\n    assert 42 == assign();\n\n    val obj = TestStruct.new(20);\n    assert 20 == obj.get_x();\n    assert 25 == obj.add_to_x(5);\n    assert 40 == obj.multiply_x(2);\n\n    val obj2 = TestStruct.new(10);\n    assert 30 == obj + obj2;\n}\n"
  },
  {
    "path": "tests/op_add.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n}\n\nextension Integer {\n    operator + (rhs) {\n        if rhs isa Integer {\n            return Integer.new(this.n + rhs.n);\n        } elsif rhs isa Int {\n            return Integer.new(this.n + rhs);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator + (lhs) {\n        if lhs isa Integer {\n            return Integer.new(lhs.n + this.n);\n        } elsif lhs isa Int {\n            return Integer.new(lhs + this.n);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return this.n == rhs;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    func prettyprint() {\n        return \"{0}\".format(this.n);\n    }\n}\n\nfunc main() {\n    val x = Integer.new(4);\n    val y = 7;\n\n    assert x + y == 11;\n\n    assert y + x == 11;\n\n    x += 2;\n    assert x isa Integer;\n    assert x == 6;\n}\n"
  },
  {
    "path": "tests/op_call.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Double {\n    operator ()(n) {\n        return n + n;\n    }\n}\n\nfunc main() {\n    val d = alloc(Double);\n\n    assert d(4) == 8;\n    assert d(\"hi\") == \"hihi\";\n}\n"
  },
  {
    "path": "tests/op_div.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n}\n\nextension Integer {\n    operator /(rhs) {\n        if rhs isa Integer {\n            return Integer.new(this.n / rhs.n);\n        } elsif rhs isa Int {\n            return Integer.new(this.n / rhs);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator /(lhs) {\n        if lhs isa Integer {\n           return Integer.new(lhs.n / this.n);\n        } elsif lhs isa Int {\n            return Integer.new(lhs / this.n);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return this.n == rhs;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    func prettyprint() {\n        return \"{0}\".format(this.n);\n    }\n}\n\nfunc main() {\n    val x = Integer.new(26);\n    val y = 4;\n\n    assert x / y == 6;\n\n    assert 9 / Integer.new(2) == 4;\n}\n"
  },
  {
    "path": "tests/op_equals.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n: Int) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return rhs == this.n;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    val n1 = 6;\n    val n2 = Integer.new(6);\n    val n3 = 7;\n    val n4 = Integer.new(7);\n\n    val flt = 3.14f;\n\n    assert n1 == n2;\n    assert n2 == n2;\n\n    assert n3 != n1;\n    assert n3 != n2;\n\n    assert n3 == n4;\n    assert n4 == n3;\n\n    assert n2 != flt;\n    assert flt != n2;\n}\n"
  },
  {
    "path": "tests/op_gt.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct StoreFive {\n    operator < (x) {\n        if x isa Int {\n            return 5 < x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator > (x) {\n        if x isa Int {\n            return 5 > x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    assert alloc(StoreFive) > 3;\n    assert !(alloc(StoreFive) > 7);\n\n    assert 8 > alloc(StoreFive);\n    assert !(4 > alloc(StoreFive));\n}\n"
  },
  {
    "path": "tests/op_gteq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct StoreFive {\n    operator <= (x) {\n        if x isa Int {\n            return 5 <= x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator >= (x) {\n        if x isa Int {\n            return 5 >= x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    assert alloc(StoreFive) >= 3;\n    assert !(alloc(StoreFive) >= 7);\n    assert alloc(StoreFive) >= 5;\n\n    assert 8 >= alloc(StoreFive);\n    assert !(4 >= alloc(StoreFive));\n    assert 5 >= alloc(StoreFive);\n}\n"
  },
  {
    "path": "tests/op_index_throws.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc expect_catch(f) {\n    try {\n        f();\n    } catch e {\n        return Result::Ok(e);\n    }\n    return Result::Err(\"no exception thrown\");\n}\n\nstruct Foo {\n    type func new() = alloc(This);\n\n    struct Error {\n        type func new() = alloc(This);\n        func prettyprint() = \"Foo.Error\";\n    }\n\n    func get(x) {\n        throw Foo.Error.new();\n    }\n\n    operator [](x) {\n        return this.get(x);\n    }\n}\n\nfunc main() {\n    val f = Foo.new();\n\n    val err = expect_catch(|| => f[1])!;\n    assert err isa Foo.Error;\n\n    val err = expect_catch(|| => f.get(1))!;\n    assert err isa Foo.Error;\n}\n"
  },
  {
    "path": "tests/op_lt.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct StoreFive {\n    operator < (x) {\n        if x isa Int {\n            return 5 < x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator > (x) {\n        if x isa Int {\n            return 5 > x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    assert alloc(StoreFive) < 6;\n    assert !(alloc(StoreFive) < 3);\n\n    assert 3 < alloc(StoreFive);\n    assert !(7 < alloc(StoreFive));\n}\n"
  },
  {
    "path": "tests/op_lteq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct StoreFive {\n    operator <= (x) {\n        if x isa Int {\n            return 5 <= x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator >= (x) {\n        if x isa Int {\n            return 5 >= x;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n}\n\nfunc main() {\n    assert alloc(StoreFive) <= 6;\n    assert !(alloc(StoreFive) <= 3);\n    assert alloc(StoreFive) <= 5;\n\n    assert 3 <= alloc(StoreFive);\n    assert !(7 <= alloc(StoreFive));\n    assert 5 <= alloc(StoreFive);\n}\n"
  },
  {
    "path": "tests/op_mul.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n}\n\nextension Integer {\n    operator * (rhs) {\n        if rhs isa Integer {\n            return Integer.new(this.n * rhs.n);\n        } elsif rhs isa Int {\n            return Integer.new(this.n * rhs);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator * (lhs) {\n        if lhs isa Integer {\n            return Integer.new(lhs.n * this.n);\n        } elsif lhs isa Int {\n            return Integer.new(lhs * this.n);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return this.n == rhs;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    func prettyprint() {\n        return \"{0}\".format(this.n);\n    }\n}\n\nfunc main() {\n    val x = Integer.new(4);\n    val y = 7;\n\n    assert x * y == 28;\n    assert y * x == 28;\n\n    assert x * y == Integer.new(28);\n    assert y * x == Integer.new(28);\n}\n"
  },
  {
    "path": "tests/op_rem.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n}\n\nextension Integer {\n    operator %(rhs) {\n        if rhs isa Integer {\n            return Integer.new(this.n % rhs.n);\n        } elsif rhs isa Int {\n            return Integer.new(this.n % rhs);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator % (lhs) {\n        if lhs isa Integer {\n            return Integer.new(lhs.n % this.n);\n        } elsif lhs isa Int {\n            return Integer.new(lhs % this.n);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return this.n == rhs;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    func prettyprint() {\n        return \"{0}\".format(this.n);\n    }\n}\n\nfunc main() {\n    val x = Integer.new(26);\n    val y = 4;\n\n    assert x % y == 2;\n\n    assert 9 % Integer.new(2) == 1;\n}\n"
  },
  {
    "path": "tests/op_sub.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Integer {\n    type func new(n) {\n        return alloc(This){\n            .n = n,\n        };\n    }\n}\n\nextension Integer {\n    operator - (rhs) {\n        if rhs isa Integer {\n            return Integer.new(this.n - rhs.n);\n        } elsif rhs isa Int {\n            return Integer.new(this.n - rhs);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    reverse operator - (lhs) {\n        if lhs isa Integer {\n            return Integer.new(lhs.n - this.n);\n        } elsif lhs isa Int {\n            return Integer.new(lhs - this.n);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    operator ==(rhs) {\n        if rhs isa Integer {\n            return rhs.n == this.n;\n        } elsif rhs isa Int {\n            return this.n == rhs;\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    func prettyprint() {\n        return \"{0}\".format(this.n);\n    }\n}\n\nfunc main() {\n    val x = Integer.new(6);\n    val y = 4;\n\n    assert x - y == 2;\n\n    assert y - x == -2;\n\n    x -= 1;\n    assert x isa Integer;\n    assert x == 5;\n\n    x-= Integer.new(1);\n    assert x isa Integer;\n    assert x == 4;\n}\n"
  },
  {
    "path": "tests/operator_overload.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new(n: Int) {\n        return alloc(This) {.n = n};\n    }\n\n    operator + (rhs: Int|Foo) {\n        if rhs isa Int {\n            return alloc(Foo) {.n = this.n + rhs};\n        } else {\n            return alloc(Foo) {.n = this.n + rhs.n};\n        }\n    }\n\n    reverse operator + (lhs: Int|Foo) {\n        if lhs isa Int {\n            return alloc(Foo) {.n = this.n + lhs};\n        } else {\n            return alloc(Foo) {.n = this.n + lhs.n};\n        }\n    }\n\n    operator - (rhs: Int|Foo) {\n        if rhs isa Int {\n            return alloc(Foo) {.n = this.n - rhs};\n        } else {\n            return alloc(Foo) {.n = this.n - rhs.n};\n        }\n    }\n\n    reverse operator - (lhs: Int|Foo) {\n        if lhs isa Int {\n            return alloc(Foo) {.n = lhs - this.n};\n        } else {\n            return alloc(Foo) {.n = lhs.n - this.n};\n        }\n    }\n\n    operator * (rhs: Int|Foo) {\n        if rhs isa Int {\n            return alloc(Foo) {.n = this.n * rhs};\n        } else {\n            return alloc(Foo) {.n = this.n * rhs.n};\n        }\n    }\n\n    reverse operator * (lhs: Int|Foo) {\n        if lhs isa Int {\n            return alloc(Foo) {.n = this.n * lhs};\n        } else {\n            return alloc(Foo) {.n = this.n * lhs.n};\n        }\n    }\n\n    operator / (rhs: Int|Foo) {\n        if rhs isa Int {\n            return alloc(Foo) {.n = this.n / rhs};\n        } else {\n            return alloc(Foo) {.n = this.n / rhs.n};\n        }\n    }\n\n    reverse operator / (lhs: Int|Foo) {\n        if lhs isa Int {\n            return alloc(Foo) {.n = lhs / this.n};\n        } else {\n            return alloc(Foo) {.n = lhs.n / this.n};\n        }\n    }\n\n    operator % (rhs: Int|Foo) {\n        if rhs isa Int {\n            return alloc(Foo) {.n = this.n % rhs};\n        } else {\n            return alloc(Foo) {.n = this.n % rhs.n};\n        }\n    }\n\n    reverse operator % (lhs: Int|Foo) {\n        if lhs isa Int {\n            return alloc(Foo) {.n = lhs % this.n};\n        } else {\n            return alloc(Foo) {.n = lhs.n % this.n};\n        }\n    }\n\n\n    operator ==(rhs: Int|Foo) {\n        if rhs isa Int {\n            return this.n == rhs;\n        } else {\n            return this.n == rhs.n;\n        }\n    }\n}\n\nfunc main() {\n    val five = Foo.new(5);\n    val ten = Foo.new(10);\n    val six = 6;\n    val three = Foo.new(3);\n\n    assert five + ten == Foo.new(15);\n    assert five + six == Foo.new(11);\n    assert ten + five == Foo.new(15);\n    assert six + five == Foo.new(11);\n\n    assert five - ten == Foo.new(-5);\n    assert five - six == Foo.new(-1);\n    assert ten - five == Foo.new(5);\n    assert six - five == Foo.new(1);\n\n    assert five * ten == Foo.new(50);\n    assert five * six == Foo.new(30);\n    assert ten * five == Foo.new(50);\n    assert six * five == Foo.new(30);\n\n    assert (five + ten) / three == Foo.new(5);\n    assert five / six == Foo.new(0);\n    assert ten / five == Foo.new(2);\n    assert six / five == Foo.new(1);\n\n    assert five % three == Foo.new(2);\n    assert five % six == Foo.new(5);\n    assert ten % five == Foo.new(0);\n    assert six % five == Foo.new(1);\n}\n"
  },
  {
    "path": "tests/opt_args_this_usage.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct S {\n    func f(a=1,...) {\n        return a + varargs.len();\n    }\n}\n\nfunc main() {\n    val s = alloc(S);\n    assert s.f() == 1;\n    assert s.f(2) == 2;\n    assert s.f(2,3,4) == 2+2;\n}\n"
  },
  {
    "path": "tests/or.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc boolean() {\n    assert (true || true) == true;\n    assert (true || false) == true;\n    assert (false || true) == true;\n    assert (false || false) == false;\n}\n\nfunc integer() {\n    val a =           0b00101110101011110001;\n    val b =           0b00010100001100011010;\n    assert (a | b) == 0b00111110101111111011;\n}\n\nfunc main() {\n    integer();\n    boolean();\n}\n"
  },
  {
    "path": "tests/or_shortcircuit.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = [1,0];\n    assert true || (x[0] / x[1] == 4);\n}"
  },
  {
    "path": "tests/ordering_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport CompareResult, TotalOrdering from aria.ordering.compare;\n\nstruct Ordered {\n    type func new(x: Int) {\n        return alloc(This){\n            .x = x,\n        };\n    }\n\n    type func int_int_compare(lhs: Int, rhs: Int) {\n        if lhs == rhs {\n            return CompareResult::eq;\n        } elsif lhs > rhs {\n            return CompareResult::gt;\n        } else {\n            return CompareResult::lt;\n        }\n    }\n\n    func comp(rhs) {\n        if rhs isa Ordered {\n            return Ordered.int_int_compare(this.x, rhs.x);\n        } elsif rhs isa Int {\n            return Ordered.int_int_compare(this.x, rhs);\n        } else {\n            throw alloc(Unimplemented);\n        }\n    }\n\n    include TotalOrdering\n}\n\nfunc main() {\n    val o3 = Ordered.new(3);\n    val o4 = Ordered.new(4);\n\n    assert (o3 == o3);\n    assert (o3 != o4);\n    assert (o4 == 4);\n    assert (o4 != 5);\n\n    assert (o3 < o4);\n    assert (o4 > o3);\n    assert (o3 < 5);\n    assert (o4 > 2);\n\n    assert (o3 <= 5);\n    assert (o4 <= 4);\n    assert (o3 <= o4);\n    assert (o4 <= o4);\n\n    assert (o3 >= 1);\n    assert (o4 >= o3);\n}\n"
  },
  {
    "path": "tests/paren_expression.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = (3 + ((((4 + 1)))));\n    assert (a == 8);\n}\n"
  },
  {
    "path": "tests/parse_enum_cases.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Blah {}\n\nenum Foo {\n    case A,\n    case B(Int),\n    case C,\n    case D(Blah)\n}\n\nfunc main() {\n    val f1 = Foo::A;\n    val f2 = Foo::B(3);\n    val f3 = Foo::C;\n    val f4 = Foo::D(alloc(Blah));\n}\n\n"
  },
  {
    "path": "tests/parse_fp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nfunc main() {\n    assert(3.14f == Float.parse(\"3.14\")!);\n    assert(5.0f == Float.parse(\"5\")!);\n    assert(-6.28f == Float.parse(\"-6.28\")!);\n\n    assert Float.parse(\"\").is_Err();\n    assert Float.parse(\"127.0.0.1\").is_Err();\n    assert Float.parse(\"-abc.def\").is_Err();\n    assert Float.parse(\"15a46\").is_Err();\n}\n"
  },
  {
    "path": "tests/parse_int.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert(12345 == Int.parse(\"12345\")!);\n    assert(67890 == Int.parse(\"67890\")!);\n    assert(-12 == Int.parse(\"-12\")!);\n    assert Int.parse(\"-0xabcdef\")! == -0xABCDEF;\n    assert Int.parse(\"0b000110011\")! == 51;\n    assert(12345 == Int.parse(\"+12345\")!);\n    assert(0 == Int.parse(\"+0\")!);\n    assert(0 == Int.parse(\"-0\")!);\n    assert Int.parse(\"0xFF\")! == 255;\n    assert Int.parse(\"0B101\")! == 5;\n    assert Int.parse(\"0O377\")! == 255;\n\n    assert Int.parse(\"\").is_Err();\n    assert Int.parse(\"-abcdef\").is_Err();\n    assert Int.parse(\"15a46\").is_Err();\n    assert Int.parse(\"0xG\").is_Err();\n    assert Int.parse(\"0b2\").is_Err();\n    assert Int.parse(\"0o8\").is_Err();\n\n    assert Int.parse_radix(\"abcDEf\", 16)! == 0xABCDEF;\n    assert Int.parse(\"-0xabcDEf\")! == -0xABCDEF;\n    assert Int.parse_radix(\"011110111\", 2)! == 0b011110111;\n    assert Int.parse_radix(\"12345\", 6)! == 1865;\n    assert Int.parse_radix(\"1A\", 31)! == 41;\n\n    assert Int.parse_radix(\"1A\", 2).is_Err();\n    assert Int.parse_radix(\"aBC\", 10).is_Err();\n    assert Int.parse_radix(\"$#@!\", 16).is_Err();\n\n    assert Int.parse_radix(\"123\", 55).is_Err();\n    assert Int.parse_radix(\"123\", 1).is_Err();\n\n    assert Int.parse(\"--10\").is_Err();\n    assert Int.parse(\"++10\").is_Err();\n    assert Int.parse(\"+-10\").is_Err();\n    assert Int.parse(\"+\").is_Err();\n    assert Int.parse(\"-\").is_Err();\n    assert Int.parse(\"1234abc\").is_Err();\n}\n"
  },
  {
    "path": "tests/pass_lambda.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(f,n) {\n    return f(n) + f(n-1);\n}\n\nfunc main() {\n    assert foo(|x| => x%5, 6) == 1;\n    assert foo(|x| => x+2, 6) == 15;\n}\n"
  },
  {
    "path": "tests/path_canonical.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\nimport Platform from aria.system.platform;\n\nfunc main() {\n    val local_platform = Platform.local();\n\n    val p = Path.new(\n        local_platform.is_Linux() ? \"/usr/bin/../bin/../lib/../../usr/bin/ls\" :\n        local_platform.is_macOS() ? \"/usr/bin/../bin/../lib/../../bin/ls\" :\n        \"<no_such_file_really_what_would_one_even_do_now>\"\n    );\n    val q = p.new_canonical().unwrap_Ok();\n\n    # on Linux, it's /usr/bin/ls; on mac it's /bin/ls\n    # checking for a suffix and whether the file exists should\n    # be sufficient\n    assert q.prettyprint().has_suffix(\"/bin/ls\");\n    assert q.exists();\n\n    val p = Path.new(\"/no/such/path/would/ever/exist/right/c:\\makeit/really/confusing/too.txt\");\n    assert p.new_canonical().is_Err();\n}\n"
  },
  {
    "path": "tests/path_checks.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\n\nfunc main() {\n    # assumes a standard Linux host\n    val binls = Path.new(\"/bin/ls\");\n    assert binls.is_file();\n    assert binls.is_absolute();\n    assert binls.exists();\n    assert binls.size()! > 0;\n    assert binls.size().is_Ok();\n    assert binls.created().is_Ok();\n    assert binls.accessed().is_Ok();\n    assert binls.modified().is_Ok();\n    assert binls.get_filename().is_Some();\n    assert binls.get_extension().is_None();\n    \n    val usrbin = Path.new(\"/usr/bin\");\n    assert usrbin.is_directory();\n    assert usrbin.is_absolute();\n    assert usrbin.size().is_Ok();\n    assert usrbin.created().is_Ok();\n    assert usrbin.accessed().is_Ok();\n    assert usrbin.modified().is_Ok();\n    assert usrbin.get_filename().is_Some();\n    assert usrbin.get_extension().is_None();\n\n    val nodir = Path.new(\"thisfiledoesnotexist/..\");\n    assert nodir.exists() == false;\n    assert nodir.is_absolute() == false;\n    assert nodir.size().is_Err();\n    assert nodir.created().is_Err();\n    assert nodir.accessed().is_Err();\n    assert nodir.modified().is_Err();\n    assert nodir.get_filename().is_None();\n    assert nodir.get_extension().is_None();\n    \n    val dnsfile = Path.new(\"/etc/resolv.conf\");\n    assert dnsfile.get_extension().is_Some();\n}\n"
  },
  {
    "path": "tests/path_common_ancestor.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\n\nfunc main() {\n    val p1 = Path.new(\"/a/b/c/d\");\n    val p2 = Path.new(\"/a/b/e/f\");\n    val ca = p1.common_ancestor(p2)!;\n    assert ca == Path.new(\"/a/b\");\n\n    val p3 = Path.new(\"/x/y/z/t\");\n    val ca2 = p1.common_ancestor(p3)!;\n    assert ca2 == Path.new(\"/\");\n}\n"
  },
  {
    "path": "tests/path_glob.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\nimport Set from aria.structures.set;\n\nfunc main() {\n    val glob_iter = Path.glob(\"**/*.aria\")!;\n    \n    val expected_paths = Set.new_with_items(\n        \"tests/path_glob.aria\",\n        \"lib/aria/io/path.aria\",\n    );\n    \n    for path in glob_iter {\n        expected_paths.remove(path.prettyprint());\n        if expected_paths.len() == 0 {\n            break;\n        }\n    }\n    \n    assert expected_paths.len() == 0;\n\n    val glob_iter = Path.glob(\"/tmp/**/*.pepepapa\")!;\n    assert glob_iter.count() == 0;\n\n    val glob_iter = Path.glob(\"a**/b/*.yml\");\n    assert glob_iter.is_Err();\n}\n"
  },
  {
    "path": "tests/path_hash.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\n\nfunc main() {\n    val p1 = Path.new(\"/some/test/path\");\n    val p2 = Path.new(\"/some/test/path\");\n\n    assert p1.hash() == p2.hash();\n    assert p1.hash() == p1.hash();\n\n    val p3 = p1  / \"subdir\" / \"file.txt\";\n    val p4 = Path.new(\"/some/test/path/subdir/file.txt\");\n    \n    assert p3.hash() == p4.hash();\n    assert p3.hash() != p1.hash();\n}\n"
  },
  {
    "path": "tests/path_io.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\nimport File from aria.io.file;\n\nfunc main() {\n    val path = Path.new_with_environment_variable(\"ARIA_TEST_DIR\").unwrap_Some();\n    path = path / \"path_io.txt\";\n\n    val msg1 = \"First line of text.\\nSecond line of text.\\nThird line of text.\";\n\n    path.write(msg1);\n\n    val msg2 = path.read();\n\n    assert msg1 == msg2;\n}\n"
  },
  {
    "path": "tests/path_io.txt",
    "content": "First line of text.\nSecond line of text.\nThird line of text."
  },
  {
    "path": "tests/path_manipulation.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Path from aria.io.path;\nimport File from aria.io.file;\n\nfunc main() {\n    val msg = \"this is a test file\";\n\n    val path = Path.new_with_environment_variable(\"ARIA_TEST_DIR\").unwrap_Some();\n\n    val src_file = path / \"path_manipulation.txt\";\n    src_file.write(msg);\n\n    val dst_file = path / \"path_manipulation\";\n    dst_file.mkdir();\n    dst_file /= \"path_manipulation.txt\";\n    src_file.copy_to(dst_file);\n\n    assert dst_file.exists();\n    assert dst_file.is_file();\n    assert dst_file.read() == msg;\n\n    dst_file.erase();\n    assert !dst_file.exists();\n\n    dst_file = dst_file.parent();\n    assert dst_file.exists();\n    assert dst_file.is_directory();\n\n    dst_file.rmdir();\n    assert !dst_file.exists();\n}\n"
  },
  {
    "path": "tests/path_manipulation.txt",
    "content": "this is a test file"
  },
  {
    "path": "tests/phi.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nassert Float.phi >= 1.6;\nassert Float.phi <= 1.7;\nassert Float.φ == Float.phi;\n"
  },
  {
    "path": "tests/platform.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Platform from aria.system.platform;\n\nfunc main() {\n    val platform = Platform.local();\n\n    assert platform.is_Linux() || platform.is_macOS();\n\n    match platform {\n        case Linux(platform) => {\n            assert platform.name() == \"Linux\";\n            assert platform.prettyprint().has_prefix(\"Linux\");\n        }\n        case macOS(platform) => {\n            assert platform.name() == \"macOS\";\n            assert platform.prettyprint().has_prefix(\"macOS\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/plus_minus_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc five() {\n    return 5;\n}\n\nfunc main() {\n    val x = 5;\n    x += 1;\n    assert x == 6;\n    x -= 3;\n    assert x == 3;\n    x += 0;\n    assert x == 3;\n    x += five();\n    assert x == 8;\n    x -= 2 * 2 + 1;\n    assert x == 3;\n}\n"
  },
  {
    "path": "tests/postfix_obj_write.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func with_one_number(x) {\n        return Foo.with_two_numbers(x,x);\n    }\n\n    type func with_two_numbers(x,y) {\n        return alloc(This) {\n            .x = x,\n            .y = y,\n        };\n    }\n}\n\nfunc main() {\n    val pair = Foo.with_two_numbers(4,5);\n    assert pair.x == 4;\n    assert pair.y == 5;\n\n    val pair = Foo.with_one_number(6);\n    assert pair.x == 6;\n    assert pair.y == 6;\n}\n"
  },
  {
    "path": "tests/prettyprint_two_arg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct PrettyprintUnary {\n    func prettyprint() {\n        return \"<PrettyprintUnary>\";\n    }\n}\n\nstruct PrettyprintBinary {\n    func prettyprint(x) {\n        if x == \"abc\" {\n            return \"123\";\n        } elsif x == \"123\" {\n            return \"abc\";\n        } elsif x == \"\" {\n            return \"<PrettyprintBinary>\";\n        } else {\n            assert(false);\n        }\n    }\n}\n\nfunc main() {\n    val s = \"unary = {0}, unary with style = {0:unused}, binary = {1}, binary with style = {1:abc}, binary with other style = {1:123}\";\n    val t = s.format(alloc(PrettyprintUnary), alloc(PrettyprintBinary));\n    assert t == \"unary = <PrettyprintUnary>, unary with style = <PrettyprintUnary>, binary = <PrettyprintBinary>, binary with style = 123, binary with other style = abc\";\n}\n"
  },
  {
    "path": "tests/queue.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport PriorityQueue from aria.structures.queue;\n\nfunc main() {\n    val pq = PriorityQueue.new();\n    \n    assert pq.len() == 0;\n\n    pq.push(5);\n    pq.push(3);\n\n    assert pq.len() == 2;\n    assert pq.pop() == 3;\n\n    pq.push(4);\n\n    assert pq.len() == 2;\n    assert pq.pop() == 4;\n    assert pq.pop() == 5;\n\n    assert pq.len() == 0;\n    assert pq.peek().is_None();\n\n    pq.push(7);\n    pq.push(2);\n    pq.push(6);\n\n    assert pq.len() == 3;\n    assert pq.peek().is_Some();\n    assert pq.peek().unwrap_Some() == 2;\n    assert pq.pop() == 2;\n    assert pq.len() == 2;\n    assert pq.peek().is_Some();\n    assert pq.peek().unwrap_Some() == 6;\n    assert pq.pop() == 6;\n    assert pq.len() == 1;\n    assert pq.peek().is_Some();\n    assert pq.peek().unwrap_Some() == 7;\n    assert pq.pop() == 7;\n    assert pq.len() == 0;\n    assert pq.peek().is_None();\n}\n"
  },
  {
    "path": "tests/queue_with_cmp.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport PriorityQueue from aria.structures.queue;\n\nfunc main() {\n    val pq = PriorityQueue.new_with_comparator(|x,y| => x > y);\n    \n    assert pq.len() == 0;\n\n    pq.push(5);\n    pq.push(3);\n\n    assert pq.len() == 2;\n    assert pq.pop() == 5;\n\n    pq.push(4);\n\n    assert pq.len() == 2;\n    assert pq.pop() == 4;\n    assert pq.pop() == 3;\n\n    assert pq.len() == 0;\n    assert pq.peek().is_None();\n\n    pq.push(7);\n    pq.push(2);\n    pq.push(6);\n\n    assert pq.len() == 3;\n    assert pq.peek().is_Some();\n    assert pq.peek().unwrap_Some() == 7;\n    assert pq.pop() == 7;\n    assert pq.len() == 2;\n    assert pq.peek().is_Some();\n    assert pq.peek().unwrap_Some() == 6;\n    assert pq.pop() == 6;\n    assert pq.len() == 1;\n    assert pq.peek().is_Some();\n    assert pq.peek().unwrap_Some() == 2;\n    assert pq.pop() == 2;\n    assert pq.len() == 0;\n    assert pq.peek().is_None();\n}\n"
  },
  {
    "path": "tests/range_hash.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Range from aria.range.range;\n\nfunc main() {\n    val r1 = Range.from(5).to(10);\n    val r2 = Range.from(6).to(10);\n    val r3 = Range.from(5).to(11);\n\n    assert r1.hash() != r2.hash();\n    assert r1.hash() != r3.hash();\n    assert r2.hash() != r3.hash();\n\n    assert r1.hash() == r1.hash();\n    assert r2.hash() == r2.hash();\n    assert r3.hash() == r3.hash();\n\n    val r4 = Range.from(6).to(10);\n\n    assert r4.hash() == r2.hash();\n    assert r2 == r4;\n}\n"
  },
  {
    "path": "tests/range_to_list.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\n\nfunc main() {\n    val r = 5.through(12);\n    val l = r.iterator().to_list();\n    assert l == [5,6,7,8,9,10,11,12];\n\n    val r = 5.to(12);\n    val l = r.iterator().to_list();\n    assert l == [5,6,7,8,9,10,11];\n}\n"
  },
  {
    "path": "tests/read_index_multiple.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new(x) = alloc(This) { .x };\n\n    operator [](a,b) {\n        return this.x * a + b;\n    }\n}\n\nfunc main() {\n    val f = Foo.new(5);\n\n    assert f[3,4] == 19;\n    assert f[2,0] == 10;\n    assert f[3,3] == 18;\n}\n"
  },
  {
    "path": "tests/read_list_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val list = [1,2,3,4,5];\n    val l0 = list[0];\n    assert l0 == 1;\n    val l1 = list[1];\n    assert l1 == 2;\n    val l2 = list[2];\n    assert l2 == 3;\n    val l3 = list[3];\n    assert l3 == 4;\n    val l4 = list[4];\n    assert l4 == 5;\n}\n"
  },
  {
    "path": "tests/read_write_val_of_function.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x) {\n    foo.NUM_CALLS += 1;\n    return x + 1;\n}\nfoo.NUM_CALLS = 0;\n\nfunc main() {\n    assert foo(3) == 4;\n    assert foo.NUM_CALLS == 1;\n\n    assert foo(4) == 5;\n    assert foo.NUM_CALLS == 2;\n\n    assert foo(foo(1)) == 3;\n    assert foo.NUM_CALLS == 4;\n}\n"
  },
  {
    "path": "tests/readattr.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new(x,y) {\n        return alloc(This) {\n            .x = x,\n            .y = y,\n            .z = x + y,\n        };\n    }\n}\n\nfunc main() {\n    val f = Foo.new(3,4);\n\n    assert readattr(f, \"x\") == 3;\n    assert readattr(f, \"y\") == 4;\n    assert readattr(f, \"z\") == 7;\n}\n"
  },
  {
    "path": "tests/redundant_local_loads.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc do_fancy_math(x,y) {\n    return x + x * (x + x + y + 1);\n}\n\nfunc main() {\n    assert do_fancy_math(4,5) == 60;\n}\n"
  },
  {
    "path": "tests/redundant_named_loads.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 4;\nval y = 5;\n\nfunc do_fancy_math() {\n    return x + x * (x + x + y + 1);\n}\n\nfunc main() {\n    assert do_fancy_math() == 60;\n}\n"
  },
  {
    "path": "tests/regex_api.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Regex from aria.string.regex;\n\nfunc main() {\n    val rgx = Regex.new(\"\\d\\d\");\n    val matches = rgx.matches(\"1234567\");\n    assert matches.len() == 3;\n    assert matches[0].value == \"12\";\n    assert matches[1].value == \"34\";\n    assert matches[2].value == \"56\";\n\n    val replaced = rgx.replace(\"abc12def5gh78ijk\", \"?\");\n    assert replaced == \"abc?def5gh?ijk\";\n}\n"
  },
  {
    "path": "tests/result.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport ok, err from aria.core.result;\n\nfunc divide_even(x: Int) {\n    if x % 2 != 0 {\n        return err(\"not even\");\n    }\n    return ok(x / 2);\n}\n\nfunc main() {\n    val r1 = divide_even(4);\n    val r2 = divide_even(5);\n\n    assert r1.is_Ok();\n    assert r2.is_Err();\n\n    assert r1.unwrap_Ok() == 2;\n    assert r2.unwrap_Err() == \"not even\";\n\n    assert Maybe.new_with_result(r1) == Maybe::Some(2);\n    assert Maybe.new_with_result(r2) == Maybe::None;\n\n    assert Result.new_with_maybe(Maybe::Some(3)) == Result::Ok(3);\n    assert Result.new_with_maybe(Maybe::None) == Result::Err(Unit.new());\n}\n"
  },
  {
    "path": "tests/result_helpers.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok, err from aria.core.result;\n\nval r1 = ok(42);\nval r2 = err(\"blah\");\n\nfunc main() {\n    assert r1.apply(|x| => x + 1) == ok(43);\n    assert r2.apply(|x| => x + 1) == err(\"blah\");\n\n    assert (r1 ?? 100) == 42;\n    assert (r2 ?? 100) == 100;\n}\n"
  },
  {
    "path": "tests/result_to_exception.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport ok, err from aria.core.result;\n\nfunc throws() {\n    throw 123;\n}\n\nfunc id(x) {\n    return x;\n}\n\nfunc main() {\n    val r1 = Result.new_with_try(throws);\n    val r2 = Result.new_with_try(|| => id(456));\n\n    assert r1.is_Err();\n    assert r2.is_Ok();\n\n    assert r1.unwrap_Err() == 123;\n    assert r2.unwrap_Ok() == 456;\n\n    assert r2.or_throw() == 456;\n\n    try {\n        r1.or_throw();\n        assert false;\n    } catch e {\n        assert e == 123;\n    }\n}\n"
  },
  {
    "path": "tests/result_unwrap.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok,err from aria.core.result;\n\nfunc calc_r(x: Result) = ok(x? + 1);\n\nassert calc_r(ok(1)) == ok(2);\nassert calc_r(err(\"e\")) == err(\"e\");\nassert calc_r(ok(1))! == 2;\n"
  },
  {
    "path": "tests/retry_test.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport * from aria.network.retry;\n\nval global = 3;\n\nfunc return_global() {\n    if global < 0 {\n        throw global;\n    }\n\n    global -= 1;\n    return global;\n}\n\nfunc main() {\n    val ok = retry(return_global, |x| => x == 1, 3, 10);\n    assert ok.is_Pass();\n    assert ok.unwrap_Pass() == 1;\n    assert ok! == 1;\n\n    global = 5;\n    val ok = retry(return_global, |x| => x == 1, 3, 10);\n    assert ok.is_Fail();\n    assert ok.unwrap_Fail().is_Some();\n    assert ok.unwrap_Fail().unwrap_Some() == 2;\n    assert global == 2;\n\n    global = 0;\n    val ok = retry(return_global, |x| => x == 1, 3, 10);\n    assert ok.is_Exception();\n    assert ok.unwrap_Exception() == -1;\n\n    global = 5;\n    val ok = retry(return_global, |x| => {\n        throw 42;\n    }, 3, 10);\n    assert ok.is_Exception();\n    assert ok.unwrap_Exception() == 42;\n\n    val ok = retry(return_global, |x| => x == 1, 0, 10);\n    assert ok.is_Fail();\n    assert ok.unwrap_Fail().is_None();\n}\n"
  },
  {
    "path": "tests/return_paren_expr.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc returnisthree(x) {\n    return (x == 3);\n}\n\nfunc compare(x,y) {\n    # return was being treated as an identifier here, so this parsed as\n    # (return(x==3)) && (y == 0);\n    # as if func return(x) {...} was a callable\n    return (x == 3) && (y == 0);\n}\n\nfunc main() {\n    assert compare(3,0);\n    assert returnisthree(3);\n}\n"
  },
  {
    "path": "tests/return_stops_eval.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    return 0;\n    assert 3 == 4;\n}\n"
  },
  {
    "path": "tests/rng_oneof.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport XorshiftRng from aria.rng.xorshift;\nimport MiddleSquareRng from aria.rng.msws;\nimport Range from aria.range.range;\n\nfunc test_rng(rng) {\n    val items = [\"pick\", \"one\", \"word\"];\n\n    val have_pick = false;\n    val have_one = false;\n    val have_word = false;\n\n    for _ in Range.from(0).to(100) {\n        val item = rng.one_of(items);\n        assert items.contains(item);\n        if item == \"pick\" {\n            have_pick = true;\n        } elsif item == \"one\" {\n            have_one = true;\n        } else {\n            have_word = true;\n        }\n    }\n\n    # This could theoretically fail, but hopefully with 100 values being\n    # generated this possibility remains very very theoretical...\n    assert have_pick && have_one && have_word;\n}\n\nfunc main() {\n    test_rng(MiddleSquareRng.new());\n    test_rng(XorshiftRng.new());\n}\n"
  },
  {
    "path": "tests/rw_int_attrib.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension Int {\n    func foo(x) {\n        return this + x;\n    }\n\n    func bar(y) {\n        return this - y;\n    }\n}\n\nfunc main() {\n    val x = 3;\n    val y = 4;\n    assert x.foo(y) == 7;\n    assert x.bar(1) == 2;\n\n    x.foo = 5;\n    assert x.foo == 5;\n    assert x.bar(2) == 1;\n\n    y.bar = 1;\n    assert y.bar == 1;\n    y.bar = x;\n    assert y.bar == 3;\n}\n"
  },
  {
    "path": "tests/rw_str_attrib.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nextension String {\n    func size() {\n        return this.len();\n    }\n\n    func double() {\n        return this * 2;\n    }\n}\n\nfunc b_double() {\n    return \"test\";\n}\n\nfunc main() {\n    val a = \"hello\";\n    val b = \"world\";\n\n    assert a.size() == 5;\n    assert b.size() == 5;\n\n    a.size = a.size() + 1;\n    assert a.size == 6;\n    assert b.size() == 5;\n\n    assert a.double() == \"hellohello\";\n    b.double = b_double();\n    assert b.double == \"test\";\n    assert a.double() == \"hellohello\";\n    assert b.size() == b.len();\n}\n"
  },
  {
    "path": "tests/set.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Set from aria.structures.set;\n\nfunc main() {\n    val s = Set.new();\n    \n    assert s.len() == 0;\n    s.set(123);\n    \n    assert s.len() == 1;\n    assert s.contains(123);\n    assert !s.contains(\"123\");\n\n    s.set(\"hello\");\n    assert s.len() == 2;\n    assert s.contains(\"hello\");\n    assert s.contains(123);\n\n    s.remove(321);\n    assert s.len() == 2;\n    assert s.contains(\"hello\");\n    assert s.contains(123);\n\n    s.remove(123);\n    assert s.len() == 1;\n    assert s.contains(\"hello\");\n    assert !s.contains(123);\n\n    s = Set.new_with_items(1, 2, 3, 4, 5);\n    assert s.len() == 5;\n    assert s.contains(3);\n    val count = 0;\n    for x in s {\n        count = count + x;\n    }\n    assert count == 15;\n}\n"
  },
  {
    "path": "tests/set_ops.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Set from aria.structures.set;\n\nfunc main() {\n    val s1 = Set.new_with_items(1,2,3,4,5);\n    val s2 = Set.new_with_items(2,4,6,8,10);\n\n    val s3 = s1.union(s2);\n    assert s3.len() == 8;\n    assert s3.contains(1);\n    assert s3.contains(2);\n    assert s3.contains(3);\n    assert s3.contains(4);\n    assert s3.contains(5);\n    assert s3.contains(6);\n    assert s3.contains(8);\n    assert s3.contains(10);\n\n    val s4 = s1.intersection(s2);\n    assert s4.len() == 2;\n    assert s4.contains(2);\n    assert s4.contains(4);\n\n    val s5 = s1.difference(s2);\n    assert s5.len() == 3;\n    assert s5.contains(1);\n    assert s5.contains(3);\n    assert s5.contains(5);\n}\n"
  },
  {
    "path": "tests/setenv.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    setenv(\"ARIA_SETENV_TEST_CASE\", \"it works\");\n    assert getenv(\"ARIA_SETENV_TEST_CASE\")! == \"it works\";\n    setenv(\"ARIA_SETENV_TEST_CASE\", \"it does not work\");\n}\n"
  },
  {
    "path": "tests/shape_failed_read_works.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.range.int_extension;\n\nstruct Foo {\n    type func new() = alloc(This) {.value = 1, .other = 2, };\n}\n\nstruct Bar {\n    type func new() = alloc(This) {.other = 3, .value = 1, };\n}\n\nstruct Baz {\n    type func new() = alloc(This) {.x = 3, .y = 5, .value = 1, };\n}\n\n# this test is rather boring without taking shapes into account\n# it checks that this \"obj.value\" read eventually fails to specialize\n# but that it still works correctly from the user's point of view\nfunc get_value(obj) { return obj.value; }\n\nfunc foo(blah) {\n    assert blah == 1;\n}\n\n# just enough to saturate the cache and then some\nfor i in 0.to(100) {\n    foo(get_value(Foo.new()));\n    foo(get_value(Bar.new()));\n    foo(get_value(Baz.new()));\n}\n"
  },
  {
    "path": "tests/shift_eq_ops.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 8;\n    x <<= 2;  \n    assert x == 32;\n\n    val y = 32;\n    y >>= 2;  \n    assert y == 8;\n\n\n    val z = 4;\n    z <<= 1;  # 4 << 1 = 8\n    z <<= 2;  # 8 << 2 = 32\n    assert z == 32;\n    z >>= 3;  # 32 >> 3 = 4\n    assert z == 4;\n\n    val a = 1;\n    a <<= 3;  # 1 << 3 = 8\n    a += 4;   # 8 + 4 = 12\n    a >>= 2;  # 12 >> 2 = 3\n    assert a == 3;\n\n    val b = 0b1010;  # 10 in decimal\n    b <<= 2;         # 0b101000 = 40\n    assert b == 40;\n    b >>= 3;         # 0b101 = 5\n    assert b == 5;\n\n    # Shift by zero (should be no-op)\n    val c = 15;\n    c <<= 0;\n    assert c == 15;\n    c >>= 0;\n    assert c == 15;\n}"
  },
  {
    "path": "tests/simple_closure.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc make_adder(n) {\n    return |x| => x + n;\n}\n\nfunc main() {\n    val add1 = make_adder(1);\n    val add2 = make_adder(2);\n\n    assert add1(3) == 4;\n    assert add2(4) == 6;\n    assert add1(add1(3)) == add2(3);\n}\n"
  },
  {
    "path": "tests/simple_default_args.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add(x: Int, y: Int = 1) {\n    return x + y;\n}\n\nfunc main() {\n    assert add(3) == 4;\n    assert add(3,4) == 7;\n}\n"
  },
  {
    "path": "tests/simple_json_parse.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport JsonValue from aria.json.parser;\n\nfunc main() {\n    val json_object = JsonValue.parse('{\"a\":1,\"b\":2}')!;\n\n    assert json_object.is_Object();\n    val map = json_object.unwrap_Object();\n\n    assert map[\"a\"].is_Number();\n    assert map[\"a\"].unwrap_Number() == 1.0f;\n\n    assert map[\"b\"].is_Number();\n    assert map[\"b\"].unwrap_Number() == 2.0f;\n}\n"
  },
  {
    "path": "tests/simple_json_parse_err.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport JsonValue from aria.json.parser;\n\nfunc main() {\n    assert JsonValue.parse('nul').is_Err();\n    assert JsonValue.parse('{\"a\":1, b:\"2\"}').is_Err();\n    assert JsonValue.parse('[1,2,3,]').is_Err();\n}\n"
  },
  {
    "path": "tests/simple_try_unwrap.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok, err from aria.core.result;\n\nfunc generates_a_result(x) {\n    if x % 2 == 0 {\n        return ok(x/2);\n    } else {\n        return err(\"not divisible by two\");\n    }\n}\n\nfunc try_double(x) {\n    val x = generates_a_result(x)?;\n    return ok(x * 4);\n}\n\nfunc main() {\n    val a = try_double(10);\n    val b = try_double(11);\n\n    assert a.is_Ok();\n    assert a? == 20;\n\n    assert b.is_Err();\n    assert b.unwrap_Err() == \"not divisible by two\";\n}\n"
  },
  {
    "path": "tests/sip_hash_test.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport SipHasher from aria.structures.hash.algo.sip;\n\nstruct Foo {\n    type func new(x,y,z) = alloc(This) { .x, .y, .z };\n\n    func hash() {\n        val hasher = SipHasher.new(0xdeadbeef, 0xabad1dea);\n        hasher.write(this.x).write(this.y).write(this.z);\n        return hasher.finish();\n    }\n}\n\nfunc main() {\n    val foo1 = Foo.new(1,2,3);\n    val foo2 = Foo.new(4,5,6);\n    \n    assert foo1.hash() != foo2.hash();\n    assert foo1.hash() == foo1.hash();\n    assert foo2.hash() == foo2.hash();\n\n    foo1.x = foo2.x;\n    foo1.y = foo2.y;\n    foo1.z = foo2.z;\n\n    assert foo1.hash() == foo2.hash();\n}\n"
  },
  {
    "path": "tests/sleep.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val before = now();\n    sleep_ms(50);\n    val after = now();\n\n    assert after - before >= 30; # allow some slack, but check that it didn't just return instantly\n    \n    val caught = false;\n    try {\n        sleep_ms(-100);\n    } catch e {\n        match e {\n            isa RuntimeError and case OperationFailed(msg) => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/stack.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Stack from aria.structures.stack;\n\nfunc main() {\n    val s = Stack.new();\n\n    assert s.len() == 0;\n    assert s.is_empty();\n\n    s.push(123);\n    s.push(false);\n    s.push(\"hello\");\n\n    assert s.len() == 3;\n    assert !s.is_empty();\n\n    assert s.peek().unwrap_Some() == \"hello\";\n    assert s.len() == 3;\n    assert !s.is_empty();\n\n    assert s.peek_at(1).unwrap_Some() == false;\n    assert s.peek_at(2).unwrap_Some() == 123;\n    assert s.peek_at(3).is_None();\n\n    assert s.try_pop().unwrap_Some() == \"hello\";\n    assert s.len() == 2;\n    assert !s.is_empty();\n\n    assert s.peek().unwrap_Some() == false;\n    assert s.peek_at(1).unwrap_Some() == 123;\n    assert s.peek_at(2).is_None();\n\n    assert s.pop() == false;\n    assert s.len() == 1;\n    assert !s.is_empty();\n\n    s.push(4*5);\n    assert s.len() == 2;\n    assert !s.is_empty();\n\n    assert s.peek_at(1).unwrap_Some() == 123;\n    assert s.pop() == 20;\n    assert s.pop() == 123;\n    assert s.len() == 0;\n    assert s.is_empty();\n\n    s.push(45);\n    assert s.len() == 1;\n    assert !s.is_empty();\n}"
  },
  {
    "path": "tests/str_chr_bytes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"ABC\";\n\n    val ch = s.chars();\n    val bt = s.bytes();\n\n    assert ch.len() == 3;\n    assert bt.len() == 3;\n\n    assert ch[0] == \"A\";\n    assert ch[1] == \"B\";\n    assert ch[2] == \"C\";\n\n    assert bt[0] == 65;\n    assert bt[1] == 66;\n    assert bt[2] == 67;\n}\n"
  },
  {
    "path": "tests/str_encoding.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val S = \"ABC 123\";\n    assert S[0].encoding() == 65;\n    assert S[1].encoding() == 66;\n    assert S[2].encoding() == 67;\n    assert S[3].encoding() == 32;\n    assert S[4].encoding() == 49;\n    assert S[5].encoding() == 50;\n    assert S[6].encoding() == 51;\n}\n"
  },
  {
    "path": "tests/str_equality.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s1 = \"hello world\";\n    val s2 = \"he\" + \"llo\" + \" wo\" + \"rld\";\n    val s3 = \"hello,\" + \" world\";\n    assert s1 == s2;\n    assert s1 != s3;\n    assert s2 != s3;\n}\n"
  },
  {
    "path": "tests/str_int_mul.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"abc\";\n\n    assert s * 0 == \"\";\n    assert s * 1 == s;\n\n\n    assert 0 * s == \"\";\n    assert 1 * s == s;\n\n    assert s * 2 == \"abcabc\";\n    assert 2 * s == \"abcabc\";\n\n    assert 2 * (s * 2) == 3 * s + s;\n    assert s * 4 == \"abcabcabcabc\";\n    assert 4 * s == \"abcabcabcabc\";\n}\n"
  },
  {
    "path": "tests/str_len_vs_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val message = \"a😀😃😄 😁😆😅 😂🤣🥲 🥹z\";\n\n    assert message.len() == 15;\n    assert message[0] == 'a';\n    assert message[1] == '😀';\n    assert message[2] == '😃';\n    assert message[3] == '😄';\n    assert message[4] == ' ';\n    assert message[5] == '😁';\n    assert message[6] == '😆';\n    assert message[7] == '😅';\n    assert message[8] == ' ';\n    assert message[9] == '😂';\n    assert message[10] == '🤣';\n    assert message[11] == '🥲';\n    assert message[12] == ' ';\n    assert message[13] == '🥹';\n    assert message[14] == 'z';\n}\n"
  },
  {
    "path": "tests/string_classes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport aria.string.classes;\n\nfunc main() {\n    assert \"ϴ\".is_uppercase_letter();\n    assert \"A\".is_letter();\n    assert \"A\".is_alphanumeric();\n    assert \"Z\".is_uppercase_letter();\n    assert \"Z\".is_letter();\n    assert \"Z\".is_alphanumeric();\n\n    assert \"ɖ\".is_lowercase_letter();\n    assert \"a\".is_letter();\n    assert \"a\".is_alphanumeric();\n\n    assert \"ϣ\".is_lowercase_letter();\n    assert \"z\".is_letter();\n    assert \"z\".is_alphanumeric();\n\n    assert \"𑇳\".is_digit();\n    assert \"0\".is_alphanumeric();\n\n    assert \"9\".is_digit();\n    assert \"9\".is_alphanumeric();\n\n    assert !\"9\".is_uppercase_letter();\n    assert !\"9\".is_lowercase_letter();\n\n    assert !\",\".is_alphanumeric();\n    assert !\"*\".is_alphanumeric();\n    assert !\" \".is_alphanumeric();\n\n    assert \" \".is_whitespace();\n    assert \"\\r\".is_whitespace();\n    assert \"\\n\".is_whitespace();\n    assert \"\\t\".is_whitespace();\n\n    try {\n        assert \"\".is_letter();\n    } catch e {\n        assert e isa RuntimeError;\n        assert e.is_IndexOutOfBounds();\n        assert e.unwrap_IndexOutOfBounds() == 0;\n    }\n}\n"
  },
  {
    "path": "tests/string_concat.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s1 = \"hello\";\n    val s2 = \", \";\n    val s3 = \"world\";\n    assert (s1+s2+s3) == \"hello, world\";\n}\n"
  },
  {
    "path": "tests/string_contains.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"hello world\";\n    assert s.contains(\"world\");\n    assert s.contains(\"llo\");\n    \n    assert !s.contains(\"test\");\n    assert !s.contains(\"world!\");\n}\n"
  },
  {
    "path": "tests/string_format.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 1;\n\n    val x_🇮🇹 = \"uno\";\n    val x_🇸🇴 = \"mid\";\n\n    val flag_it = \"🇮🇹\";\n    val flag_so = \"🇸🇴\";\n\n    val fmt_str = \"The number {0} is written {1} in {2} and {3} in {4}\";\n    val out = fmt_str.format(x,x_🇮🇹,flag_it,x_🇸🇴,flag_so);\n\n    assert out == \"The number 1 is written uno in 🇮🇹 and mid in 🇸🇴\";\n}\n"
  },
  {
    "path": "tests/string_format_errors.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc format_assert(x, y) {\n    # println(\"actual: '{0}' expected: '{1}'\".format(x, y));\n    assert x == y;\n}\nfunc main() {\n    format_assert(\"{a}\".format(), \"{a}\");\n    format_assert(\"{12a}\".format(0), \"{12a}\");\n    format_assert(\"{0:\".format(5), \"{0:\");\n    format_assert(\"{\".format(), \"{\");\n    format_assert(\"}\".format(), \"}\");\n    format_assert(\"{{{0}}}\".format(7), \"{7}\");\n    format_assert(\"{0}{1}\".format(\"a\",\"b\"), \"ab\");\n    format_assert(\"{2}\".format(1,2), \"{2}\");\n}\n"
  },
  {
    "path": "tests/string_from_bytes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val bytes = [65, 66, 67, 68, 69];\n    val s = String.new_with_bytes(bytes);\n    assert s == \"ABCDE\";\n}\n"
  },
  {
    "path": "tests/string_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"hello world\";\n    assert s[0] == \"h\";\n    assert s[2] == s[3];\n    assert s[3] == s[9];\n    assert s[10] == \"d\";\n}\n"
  },
  {
    "path": "tests/string_join.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nstruct SampleIterator {\n    type func new() = alloc(This) {.num = 0};\n\n    instance func iterator() = this;\n\n    instance func next() {\n        if this.num == 5 {\n            return Maybe::None;\n        } else {\n            this.num += 1;\n            return Maybe::Some(this.num);\n        }\n    }\n}\n\nfunc main() {\n    val l = [1,2,3,4];\n    assert \"\".join(l) == \"1234\";\n    assert \", \".join(l) == \"1, 2, 3, 4\";\n    assert \"-\".join(l) == \"1-2-3-4\";\n    assert l.join() == \"1, 2, 3, 4\";\n\n    assert \",\".join([]) == \"\";\n    assert \",\".join([1]) == \"1\";\n\n    assert \"\".join([]) == \"\";\n\n    assert \"::\".join(SampleIterator.new()) == \"1::2::3::4::5\";\n}\n"
  },
  {
    "path": "tests/string_negative_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = \"Hello\";\n\nassert x[-1] == \"o\";\nassert x[-2] == \"l\";\nassert x[-5] == \"H\";\n\ntry {\n    println(x[-6]);\n} catch e {\n    assert e isa RuntimeError;\n    assert e.is_IndexOutOfBounds();\n}\n"
  },
  {
    "path": "tests/string_prefix_suffix.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert(\"hello\".has_prefix(\"he\"));\n    assert(\"hello\".has_suffix(\"lo\"));\n\n    assert !\"hello\".has_prefix(\"123\");\n    assert !\"hello\".has_suffix(\"123\");\n}\n"
  },
  {
    "path": "tests/string_product_negative.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nassert \"hello\"*-3 == \"\";\nassert \"aria\"*0 == \"\";\nassert \"test\"*-2 == \"\";\n"
  },
  {
    "path": "tests/string_remove.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval s = \"Hello, World! This is such a, lovely, wonderful even, day.\";\nval s2 = s.remove(\",\").remove(\"!\").remove(\".\");\nassert s2 == \"Hello World This is such a lovely wonderful even day\";\n"
  },
  {
    "path": "tests/string_replace.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"hello world\";\n    s = s.replace(\"h\", \"H\").replace(\" \", \", \").replace(\"d\", \"d!\").replace(\" w\", \" W\").replace(\"X\", \"Y\");\n    assert s == \"Hello, World!\";\n}\n"
  },
  {
    "path": "tests/string_split.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = \"one two three four five words\";\n    val l = s.split(\" \");\n    assert l.len() == 6;\n    assert l[0] == \"one\";\n    assert l[1] == \"two\";\n    assert l[2] == \"three\";\n    assert l[3] == \"four\";\n    assert l[4] == \"five\";\n    assert l[5] == \"words\";\n}\n"
  },
  {
    "path": "tests/string_trim.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val string = \"\\n Hello World! \\n\";\n\n    assert string.trim() == \"Hello World!\";\n    assert string.trim_head() == \"Hello World! \\n\";\n    assert string.trim_tail() == \"\\n Hello World!\";\n}\n"
  },
  {
    "path": "tests/strings_anagram_hash.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nassert \"listen\".hash() != \"silent\".hash();\n\nassert \"\".hash() == \"\".hash();\n\nassert \"a\".hash() != \"A\".hash();\n"
  },
  {
    "path": "tests/strlen.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val s = 'hello world';\n    val t = '';\n\n    assert s.len() == 11;\n    assert t.len() == 0;\n}\n"
  },
  {
    "path": "tests/struct_field.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type val MAX_VALUE = 3;\n\n    type func new(n) {\n        if n > Foo.MAX_VALUE {\n            n = Foo.MAX_VALUE;\n        }\n        return alloc(This) {\n            .n = n,\n        };\n    }\n}\n\nfunc main() {\n    val foo_2 = Foo.new(2);\n    val foo_4 = Foo.new(4);\n\n    Foo.MAX_VALUE = 5;\n    val foo_5 = Foo.new(5);\n\n    assert foo_2.n == 2;\n    assert foo_4.n == 3;\n    assert foo_5.n == 5;\n\n    # should this actually work?\n    assert foo_2.MAX_VALUE == 5;\n}\n"
  },
  {
    "path": "tests/struct_func_redecl.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Test {\n    func answer() {\n        return \"A\";\n    }\n\n    func answer() {\n        return \"B\";\n    }\n}\n\nfunc main() {\n    val test = alloc(Test);\n\n    assert test.answer() == \"B\";\n}\n"
  },
  {
    "path": "tests/struct_in_enum.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum X {}\n\nextension X {\n    struct Pair {\n        type func new(x,y) {\n            return alloc(This) {\n                .x=x,\n                .y=y,\n            };\n        }\n    }\n}\n\nextension X.Pair {\n    instance func swap() {\n        return X.Pair.new(this.y,this.x);\n    }\n}\n\nval Pair = X.Pair;\n\nfunc main() {\n    val p = Pair.new(3,4);\n    val q = p.swap();\n    \n    assert q.x == 4;\n    assert q.y == 3;\n}\n"
  },
  {
    "path": "tests/struct_in_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Outer {\n    struct Inner {\n        type func new(x,y) {\n            return alloc(This) {\n                .x = x,\n                .y = y,\n            };\n        }\n\n        func i_add() {\n            return this.x + this.y;\n        }\n\n        func i_sub() {\n            return this.x - this.y;\n        }\n\n        func i_swap() {\n            val x = this.x;\n            val y = this.y;\n            this.x = y;\n            this.y = x;\n            return this;\n        }\n    }\n\n    type func new(x,y) {\n        return alloc(This) {\n            .impl = Outer.Inner.new(x,y),\n        };\n    }\n\n    func add() {\n        return this.impl.i_add();\n    }\n\n    func swap() {\n        return this.impl.i_swap();\n    }\n\n    func sub() {\n        return this.impl.i_sub();\n    }\n}\n\nfunc main() {\n    val o = Outer.new(8,2);\n    assert o.add() == 10;\n    o.swap();\n    assert o.sub() == -6;\n\n    # check that names are unique between Outer and Inner\n    assert !hasattr(o, \"i_swap\");\n    assert !hasattr(o.impl, \"swap\");\n\n    assert hasattr(Outer, \"Inner\");\n}\n"
  },
  {
    "path": "tests/struct_isa_mixin.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nmixin M {\n    func foo(x) {\n        return x + 1;\n    }\n}\n\nmixin MM {\n    func bar(x) {\n        return this.foo(x) + 1;\n    }\n\n    include M\n}\n\nstruct IncludeM {\n    include M\n}\n\nstruct IncludeMM {\n    include MM\n}\n\nfunc main() {\n    val m = alloc(IncludeM);\n    val mm = alloc(IncludeMM);\n\n    assert m isa M;\n    assert mm isa MM;\n    assert mm isa M;\n\n    assert !(m isa MM);\n\n    assert MM isa M;\n    assert !(M isa MM);\n\n    assert IncludeM isa M;\n    assert !(IncludeM isa MM);\n    assert IncludeMM isa MM;\n    assert IncludeMM isa M;\n}\n"
  },
  {
    "path": "tests/struct_list_attributes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func f1(x) {\n        return x + 1;\n    }\n    func f2(x) {\n        return x * 2;\n    }\n    func f3(x) {\n        return x + 3;\n    }\n}\n\nextension Foo {\n    func f4(x) {\n        return x + 4;\n    }\n    func f5(x) {\n        return x + 5;\n    }\n    func f6(x) {\n        return x + 6;\n    }\n}\n\nstruct Bar {\n    func f1(x) {\n        return x + 1;\n    }\n    func f2(x) {\n        return x * 2;\n    }\n    func f3(x) {\n        return x + 3;\n    }\n}\n\nmixin PlusSeven {\n    func f7(x) {\n        return x + 7;\n    }\n}\n\nextension Bar {\n    include PlusSeven\n}\n\nfunc main() {\n    val f = alloc(Foo);\n    val b = alloc(Bar);\n\n    val attribs_f = listattrs(f);\n    val attribs_b = listattrs(b);\n\n    assert attribs_f.contains(\"f1\");\n    assert attribs_f.contains(\"f2\");\n    assert attribs_f.contains(\"f3\");\n    assert attribs_f.contains(\"f4\");\n    assert attribs_f.contains(\"f5\");\n    assert attribs_f.contains(\"f6\");\n    assert attribs_f.len() == 6;\n\n    assert attribs_b.contains(\"f1\");\n    assert attribs_b.contains(\"f2\");\n    assert attribs_b.contains(\"f3\");\n    assert attribs_b.contains(\"f7\");\n    assert attribs_b.len() == 4;\n\n    val attribs_m = listattrs(PlusSeven);\n    assert attribs_m.contains(\"f7\");\n    assert attribs_m.len() == 1;\n}\n"
  },
  {
    "path": "tests/struct_methods_refer_each_other.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func add_one(x) {\n        return x + 1;\n    }\n    func add_two(x) {\n        return this.add_one(this.add_one(x));\n    }\n}\n\nextension Foo {\n    func add_three(x) {\n        return this.add_two(this.add_one(x));\n    }\n}\n\nfunc main() {\n    val foo = alloc(Foo);\n    assert foo.add_one(3) == 4;\n    assert foo.add_two(4) == 6;\n    assert foo.add_three(6) == 9;\n}\n"
  },
  {
    "path": "tests/struct_methods_refer_outoforder.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func add_two(x) {\n        return this.add_one(this.add_one(x));\n    }\n\n    func add_one(x) {\n        return x + 1;\n    }\n}\n\nextension Foo {\n    func add_three(x) {\n        return this.add_two(this.add_one(x));\n    }\n}\n\nfunc main() {\n    val foo = alloc(Foo);\n    assert foo.add_one(3) == 4;\n    assert foo.add_two(4) == 6;\n    assert foo.add_three(6) == 9;\n}\n"
  },
  {
    "path": "tests/struct_mixin_multiple.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nmixin A {\n    func from_a() { return \"A\"; }\n}\n\nmixin B {\n    func from_b() { return \"B\"; }\n}\n\nstruct Multi : A, B {\n    type func new() {\n        return alloc(This);\n    }\n}\n\nfunc main() {\n    val m = Multi.new();\n    assert m.from_a() == \"A\";\n    assert m.from_b() == \"B\";\n}"
  },
  {
    "path": "tests/struct_takes_self_arg.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    func take_myself(x: Foo) {\n        return 42;\n    }\n}\n\nfunc main() {\n    val f = alloc(Foo);\n    assert f.take_myself(f) == 42;\n}\n"
  },
  {
    "path": "tests/struct_with_opt_args.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct UseOptionalArguments {\n    type func new(value: Int) {\n        return alloc(This) {\n            .value = value,\n        };\n    }\n\n    func only_optionals(x=1,y=2) {\n        return x + y * this.value;\n    }\n\n    func some_optionals(x, y=3,z=4) {\n        return x * y + this.value + z;\n    }\n\n    func opt_with_vararg(x,y=1,...) {\n        val ret = x+y;\n        for arg in varargs {\n            ret *= arg;\n        }\n        return ret;\n    }\n}\n\nfunc main() {\n    val uoa = UseOptionalArguments.new(5);\n    \n    assert uoa.only_optionals() == 11;\n    assert uoa.only_optionals(2) == 12; \n    assert uoa.only_optionals(3,4) == 23;\n\n    assert uoa.some_optionals(2) == 15;\n    assert uoa.some_optionals(2, 5) == 19;\n    assert uoa.some_optionals(2, 4, 3) == 16;\n\n    assert uoa.opt_with_vararg(1) == 2;\n    assert uoa.opt_with_vararg(1, 2) == 3;\n    assert uoa.opt_with_vararg(1, 2, 3) == 9;\n    assert uoa.opt_with_vararg(1, 2, 3, 4) == 36;\n}\n"
  },
  {
    "path": "tests/substring.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val str = \"hello world\";\n\n    assert str.substring(0,1) == \"he\";\n    assert str.substring(0,4) == \"hello\";\n\n    assert str.substring(6,100) == \"world\";\n    assert str.substring(5,6) == \" w\";\n}\n"
  },
  {
    "path": "tests/successive_ifs.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val n = 3;\n    val m = 4;\n\n    if n == 3 {\n        m = m + 1;\n    } else {\n        m = 2;\n    }\n\n    if m == 5 {\n        n = 2;\n    } else {\n        n = 1;\n    }\n\n    assert n == 2;\n    assert m == 5;\n\n    if n != 2 {\n        assert false;\n    } elsif m != 5 {\n        assert false;\n    } else {\n        assert m + n == 7;\n    }\n}\n"
  },
  {
    "path": "tests/system_of_no_such_cmd_err.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val caught = false;\n\n    try {\n        val ok = system(\"this_command_does_not_exist.no-such-file\");\n        caught = ok != 0;\n    } catch e {\n        match e {\n            isa RuntimeError and case OperationFailed => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/ternary_operator.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nfunc main() {\n    val x = true ? 123 : 456;\n    assert x == 123;\n\n    val y = false ? 123 : 456;\n    assert y == 456;\n\n    val z = 1 == 1 ? 789 : 1011;\n    assert z == 789;\n\n    val a = 1 != 1 ? 789 : 1011;\n    assert a == 1011;\n}\n"
  },
  {
    "path": "tests/ternary_operator_nested.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nfunc main() {\n    val x = true ? (false ? 1 : 2) : 3;\n    assert x == 2;\n\n    val y = false ? 1 : (true ? 2 : 3);\n    assert y == 2;\n\n    val z = true ? (true ? (false ? 1 : 2) : 3) : 4;\n    assert z == 2;\n\n    val n = x == 1 ? \"one\" : x == 2 ? \"two\" : \"three\";\n    assert n == \"two\";\n}\n"
  },
  {
    "path": "tests/ternary_operator_precedence.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nfunc main() {\n    val x = 1 + 2 == 3 ? 10 : 20;\n    assert x == 10;\n\n    val y = 1 + 2 != 3 ? 10 : 20;\n    assert y == 20;\n\n    val a = true && false ? 100 : 200;\n    assert a == 200;\n\n    val b = true || false ? 100 : 200;\n    assert b == 100;\n}\n"
  },
  {
    "path": "tests/test_module.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport TestSuite,TestCase from aria.test.test;\n\nstruct SamplePassingTest {\n    func test() {\n        this.assert_equal(5, 5);\n    }\n\n    func prettyprint() {\n        return \"SamplePassingTest\";\n    }\n\n    include TestCase\n}\n\nstruct SampleFailingTest {\n    func test() {\n        this.assert_equal(\"hi\", \"hello\");\n    }\n\n    func prettyprint() {\n        return \"SampleFailingTest\";\n    }\n\n    include TestCase\n}\n\n\nfunc main() {\n    val suite = TestSuite.new(\"Sample Test Suite\");\n    assert suite.add_test(SamplePassingTest.new()).add_test(SampleFailingTest.new()).run(true) == 1;\n}\n"
  },
  {
    "path": "tests/test_shell_command.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    # only run a very minimal test\n\n    # TODO: on macOS, this is nominally deprecated and it should be \"id -un\" instead\n    # however, it appears to still work\n    val whoami = system(\"whoami\");\n    assert whoami == 0;\n    assert whoami.stdout != \"\";\n    assert whoami.stderr == \"\";\n}\n"
  },
  {
    "path": "tests/test_with_no_main.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 3;\nval y = x + 1;\nassert x == 3;\nassert y == 4;\n"
  },
  {
    "path": "tests/throw_in_catch.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val inner = false;\n    val outer = false;\n    try {\n        try {\n            throw 1;\n        } catch e {\n            inner = e;\n            throw 2;\n        }\n    } catch e {\n        outer = e;\n    }\n\n    assert inner == 1;\n    assert outer == 2;\n}\n"
  },
  {
    "path": "tests/throws_func.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc throws() {\n    return 1;\n}\n\nfunc main() {\n    throws();\n}\n"
  },
  {
    "path": "tests/to_json_string.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.json.writer;\nimport aria.json.parser;\nimport JsonValue, JsonNull from aria.json.value;\nimport Map from aria.structures.map;\n\nfunc main() {\n    val json_value = JsonValue::Object(Map.new() {\n        [\"pi\"] = JsonValue::Number(3.14f),\n        [\"zero\"] = JsonValue::Number(0.0f),\n        [\"false\"] = JsonValue::Boolean(false),\n        [\"list\"] = JsonValue::Array([\n            JsonValue::String(\"hello world\"),\n            JsonValue::Number(1.0f),\n            JsonValue::Null(alloc(JsonNull))\n        ]),\n    });\n\n    val json_as_string = json_value.to_json_string();\n    \n    assert json_as_string.contains('\"zero\":0');\n    assert json_as_string.contains('\"list\":[');\n    assert json_as_string.contains('\"false\":false');\n\n    val json_remade = JsonValue.parse(json_as_string)!.flatten();\n\n    assert json_remade[\"pi\"] == 3.14f;\n    assert json_remade[\"zero\"] == 0.0f;\n    assert json_remade[\"false\"] == false;\n    assert json_remade[\"list\"].len() == 3;\n    assert json_remade[\"list\"][0] == \"hello world\";\n    assert json_remade[\"list\"][1] == 1.0f;\n    assert json_remade[\"list\"][2] isa JsonNull;\n}\n"
  },
  {
    "path": "tests/to_json_value.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.json.writer;\nimport JsonValue from aria.json.value;\nimport Map from aria.structures.map;\n\nfunc main() {\n    val map = Map.new();\n    map[\"hello\"] = [1,2,3];\n    map[\"hi\"] = false;\n    map[\"foo\"] = 3.14f;\n\n    val json_map = JsonValue.new_with_value(map)!;\n\n    assert json_map isa JsonValue;\n\n    val unwrap_map = json_map.unwrap_Object();\n    assert unwrap_map isa Map;\n\n    assert unwrap_map[\"hello\"].is_Array();\n    val array = unwrap_map[\"hello\"].flatten();\n    assert array.len() == 3;\n    assert array[0] == 1;\n    assert array[1] == 2;\n    assert array[2] == 3;\n\n    assert unwrap_map[\"hi\"].is_Boolean();\n    assert unwrap_map[\"hi\"].flatten() == false;\n\n    assert unwrap_map[\"foo\"].is_Number();\n    assert unwrap_map[\"foo\"].flatten() == 3.14f;\n}\n"
  },
  {
    "path": "tests/top_level_assign.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1;\nval y = 3;\nx = y + x;\ny = y + 2;\n\nassert x == 4;\nassert y == 5;\n\nfunc main() {\n    assert x == 4;\n    assert y == 5;\n}\n"
  },
  {
    "path": "tests/top_level_code_block.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval worked = false;\n\nval q = 10;\n\n{\n    val x = 1;\n    val y = 2;\n    assert x + y == 3;\n    while q > 0 {\n        if q == 3 {\n            break;\n        }\n        q -= 1;\n    }\n    worked = (q == 3);\n}\n\nfunc main() {\n    assert worked;\n    assert q == 3; # right now, all things top level are visible\n}\n"
  },
  {
    "path": "tests/top_level_expr_stmt.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval global = 0;\n\nfunc increase() {\n    global += 1;\n}\n\nincrease();\n\nfunc main() {\n    assert global == 1;\n}\n"
  },
  {
    "path": "tests/top_level_guard.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct Guard {\n    type val COUNTER = 0;\n\n    instance func guard_exit() {\n        Guard.COUNTER = Guard.COUNTER + 1;\n    }\n}\n\nval in_guard = guard(alloc(Guard)).do(|g| => {\n    assert 3 == 3;\n    return true;\n});\n\nfunc main() {\n    assert Guard.COUNTER == 1;\n    assert in_guard;\n}\n"
  },
  {
    "path": "tests/top_level_plus_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 1;\n\nx += 2;\n\nfunc main() {\n    assert x == 3;\n}\n"
  },
  {
    "path": "tests/top_level_shift_eq.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval x = 4;\n\nx <<= 2; \n\nval y = x; \n\ny >>= 3; \n\nfunc main() {\n    assert x == 16;\n    assert y == 2;\n}"
  },
  {
    "path": "tests/top_level_try.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval caught = false;\nval should_have_failed = false;\n\ntry {\n    println(3 / 0);\n    should_have_failed = true;\n} catch e {\n    match e {\n        isa RuntimeError and case DivisionByZero => { caught = true; }\n    }\n}\n\nfunc main() {\n    assert caught;\n    assert !should_have_failed;\n}\n"
  },
  {
    "path": "tests/trig.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n\nimport aria.numerics.float.trig;\n\nval π = Float.pi;\n\nfunc rough_approx_eq(x: Float, y: Float) {\n    return (x-y).abs() <= 0.00001f;\n}\n\nfunc main() {\n    assert(rough_approx_eq((π/6.0f).sin(), 0.5f));\n    assert(rough_approx_eq((π/6.0f).cos(), 0.8660254f));\n\n    assert(rough_approx_eq((0.0f).sin(), 0.0f));\n    assert(rough_approx_eq((0.0f).cos(), 1.0f));\n\n    assert(rough_approx_eq((π/2.0f).sin(), 1.0f));\n    assert(rough_approx_eq((π/2.0f).cos(), 0.0f));\n\n    assert(rough_approx_eq(π.sin(), 0.0f));\n    assert(rough_approx_eq(π.cos(), -1.0f));\n\n    assert(rough_approx_eq(0.0f.arcsin(), 0.0f));\n    assert(rough_approx_eq(0.5f.arcsin(), π/6.0f));\n    assert(rough_approx_eq((-0.5f).arcsin(), -π/6.0f));\n\n    assert(rough_approx_eq(0.0f.arccos(), π/2.0f));\n    assert(rough_approx_eq(0.5f.arccos(), π/3));\n    assert(rough_approx_eq((-0.5f).arccos(), 2*π/3));\n}\n"
  },
  {
    "path": "tests/trivial_if.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 0;\n    if true {\n        for a in [1,2,3,4] {\n            x = a;\n        }\n    }\n    if false {\n        x = 2;\n    }\n\n    assert x == 4;\n}\n"
  },
  {
    "path": "tests/trivial_try_block.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 1;\n    try {\n        x = 2;\n        throw 3;\n    } catch e {\n        assert e == 3;\n        x = x + 1;\n    }\n    assert x == 3;\n}\n"
  },
  {
    "path": "tests/try_nothrow.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 1;\n    try {\n        x = 3;\n    } catch e {\n        assert false;\n    }\n    assert x == 3;\n}\n"
  },
  {
    "path": "tests/try_unwinds_guard.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport guard from aria.utils.guard;\n\nstruct Guard {\n    type func new(x: Int) {\n        return alloc(This) {\n            .counter = x,\n        };\n    }\n\n    func guard_exit() {\n        this.counter = this.counter + 1;\n    }\n}\n\nfunc main() {\n    val g1 = Guard.new(1);\n    val g2 = Guard.new(2);\n\n    try {\n        guard(g1).do(|_| => {\n            guard(g2).do(|_| => {\n                throw 4;\n            });\n        });\n    } catch e {\n        assert e == 4;\n        assert g1.counter == 2;\n        assert g2.counter == 3;\n    }\n\n    assert g1.counter == 2;\n    assert g2.counter == 3;\n}\n"
  },
  {
    "path": "tests/try_unwrap_coalesce.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport ok, err from aria.core.result;\n\nval called = false;\n\nfunc fallback() {\n    called = true;\n    return 99;\n}\n\nfunc main() {\n    val ok_val = ok(5);\n    val err_val = err(\"nope\");\n\n    val a = ok_val ?? fallback();\n    assert a == 5;\n    assert called == false;\n\n    called = false;\n    val b = err_val ?? fallback();\n    assert b == 99;\n    assert called == true;\n\n    assert (Maybe::Some(3) ?? 7) == 3;\n    assert (Maybe::None ?? 7) == 7;\n\n    val chained = err(\"bad\") ?? ok(10) ?? 20;\n    assert chained == 10;\n\n    val chained = err(\"bad\") ?? err(10) ?? 20;\n    assert chained == 20;\n}\n"
  },
  {
    "path": "tests/try_unwrap_maybe.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val a = Maybe::Some(5);\n    val b = Maybe::None;\n\n    assert a? == 5;\n    assert b?.is_Err();\n}\n"
  },
  {
    "path": "tests/try_unwrap_non_result.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    assert 5? == 5;\n    assert false? == false;\n    assert 3! == 3;\n    assert \"hello\"! == \"hello\";\n}\n"
  },
  {
    "path": "tests/type_func_takes_This.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Pair{\n    type func new_with_duplicate(x) {\n        assert hasattr(This, \"new_with_items\");\n        return This.new_with_items(x,x);\n    }\n    type func new_with_items(x,y) {\n        return alloc(This){\n            .x = x,\n            .y = y,\n        };\n    }\n}\n\nfunc main() {\n    val p = Pair.new_with_duplicate(5);\n    assert p.x == 5;\n    assert p.y == 5;\n}\n"
  },
  {
    "path": "tests/type_root.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new() = alloc(This);\n};\n\nfunc main() {\n    val one = 1;\n    val s = Maybe::Some(3);\n    val f = Foo.new();\n\n    val t_one = typeof(one);\n    val t_s = typeof(s);\n    val t_f = typeof(f);\n\n    assert t_one != t_s;\n    assert t_one != t_f;\n    assert t_s != t_f;\n\n    val t_t_one = typeof(t_one);\n    val t_t_s = typeof(t_s);\n    val t_t_f = typeof(t_f);\n\n    assert t_t_one == t_t_s;\n    assert t_t_one == t_t_f;\n    assert t_t_s == t_t_f;\n\n    val t_t_t_one = typeof(t_t_one);\n    val t_t_t_s = typeof(t_t_s);\n    val t_t_t_f = typeof(t_t_f);\n\n    assert t_t_t_one == t_t_t_s;\n    assert t_t_t_one == t_t_t_f;\n    assert t_t_t_s == t_t_t_f;\n\n    assert t_t_t_one == t_t_one;\n    assert t_t_t_s == t_t_s;\n    assert t_t_t_f == t_t_f;\n}\n"
  },
  {
    "path": "tests/type_val_in_enum.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nenum Foo {}\n\nextension Foo {\n    type val ANSWER = 42;\n}\n\nfunc main() {\n    assert Foo.ANSWER == 42;\n}"
  },
  {
    "path": "tests/typecheck_as_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new() {\n        return alloc(This);\n    }\n\n    instance func truth() {\n        return true;\n    }\n}\n\nfunc main() {\n    val f: Foo = Foo.new();\n    assert(f.truth());\n}\n"
  },
  {
    "path": "tests/unexpected_type_error.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val caught = false;\n\n    try {\n        assert 1 + \"hello\" == false;\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n}\n"
  },
  {
    "path": "tests/union_type_passes.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\n# this is not *exactly* right - ideally it would be\n# x: Int|String, y: typeof(x) - but we can't express that\nfunc foo(x: Int|String, y:Int|String) {\n    assert typeof(x) == typeof(y); # this is the next best thing\n    return x + y;\n}\n\nfunc main() {\n    assert foo(4,5) == 9;\n    assert foo(\"hello\", \"world\") == \"helloworld\";\n}\n"
  },
  {
    "path": "tests/unit_type.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val nu = Unit.new();\n    val uu = Unit::unit;\n\n    assert nu == uu;\n    assert nu.prettyprint() == \"unit\";\n}\n"
  },
  {
    "path": "tests/unused_local_typechecks.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x: Int) {\n    return 0;\n}\n\nfunc bar(y) {\n    return 0;\n}\n\nfunc main() {\n    foo(3);\n    bar(3);\n\n    val caught = false;\n    try {\n        foo(\"abc\");\n    } catch e {\n        match e {\n            isa RuntimeError and case UnexpectedType => {\n                caught = true;\n            }\n        }\n    }\n\n    assert caught;\n\n    bar(\"abc\");\n}\n"
  },
  {
    "path": "tests/unused_local_value.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x) {\n    val y = x + 1;\n    return x;\n}\n\nfunc main() {\n    assert foo(4) == 4;\n}\n"
  },
  {
    "path": "tests/unused_typed_local.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x: Int, y) {\n    return y + 1;\n}\n\nfunc main() {\n    assert foo(3,4) == 5;\n}\n"
  },
  {
    "path": "tests/unwrap_single_eval.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nval c = 0;\nfunc bump() {\n    c = c + 1;\n    return Maybe::Some(c);\n}\n\nbump()?; bump()?;\nassert c == 2;\nassert bump()? == 3;\nassert bump()! == 4;\n"
  },
  {
    "path": "tests/uplevel_can_write_attrib.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val variable = Box();\n    variable.foo = 1;\n    val g = || => {\n        variable.foo = 3;\n        return variable;\n    };\n    assert g().foo == 3;\n    assert variable.foo == 3;\n}\n"
  },
  {
    "path": "tests/uplevel_write_before_read.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val variable = 10;\n    val g = || => {\n        variable = 11;\n        return variable;\n    };\n    assert g() == 11;\n    assert variable == 10;\n}\n"
  },
  {
    "path": "tests/upper_lower.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val str = \"Hello, World!\";\n\n    val u = str.uppercase();\n    val l = str.lowercase();\n\n    assert u == \"HELLO, WORLD!\";\n    assert l == \"hello, world!\";\n}\n"
  },
  {
    "path": "tests/while_break.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val i = 0;\n    while i != 10 {\n        i = i + 1;\n        if i == 4 {\n            break;\n        }\n    }\n\n    assert i == 4;\n}\n"
  },
  {
    "path": "tests/while_continue.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val i = 0;\n    while i != 10 {\n        i = i + 1;\n        continue;\n        assert false;\n    }\n\n    assert i == 10;\n}\n"
  },
  {
    "path": "tests/while_else.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val x = 3;\n\n    while x > 0 {\n        x -= 1;\n    } else {\n        assert false; # this should not execute\n    }\n\n    assert x == 0;\n\n    while x > 0 {\n        assert false; # this should not execute\n    } else {\n        x = 5;\n    }\n\n    assert x == 5;\n}"
  },
  {
    "path": "tests/while_missed.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc loop_forever_or_never(b) {\n    val counter = 721;\n    while b {\n        counter = counter + 1;\n    }\n    return counter;\n}\n\nfunc main() {\n    val c = loop_forever_or_never(false);\n    assert c == 721;\n}\n"
  },
  {
    "path": "tests/while_taken.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc add_them_up(n) {\n    val counter = 0;\n    val i = 0;\n    while i != n {\n        counter = counter + i;\n        i = i + 1;\n    }\n    return counter + n;\n}\n\nfunc main() {\n    val total = add_them_up(6);\n    assert total == 21;\n}\n"
  },
  {
    "path": "tests/widget_test.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport Paco from cool_widget.lib;\nimport BWrapper from cool_widget.lib;\nimport AWrapper from cool_widget.lib;\nimport Buzz from cool_widget.buzz;\n\nfunc main() {\n    val buzz = Paco.build_buzz();\n    val real_buzz = alloc(Buzz);\n    \n    assert(buzz.prettyprint() == real_buzz.prettyprint());\n    \n    val a = AWrapper.new();\n    val b = BWrapper.new();\n    \n    assert(a.prettyprint() == \"A\");\n    assert(b.prettyprint() == \"InnerB\");\n}\n"
  },
  {
    "path": "tests/write_attrib_struct.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {}\n\nfunc main() {\n    Foo{.x = 1};\n    assert Foo.x == 1;\n}\n"
  },
  {
    "path": "tests/write_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val arr = []{\n        [0] = 1,\n        [1] = 2,\n        [2] = 3,\n        [3] = 4,\n    };\n\n    assert arr.len() == 4;\n    assert arr[0] == 1;\n    assert arr[1] == 2;\n    assert arr[2] == 3;\n    assert arr[3] == 4;\n}\n"
  },
  {
    "path": "tests/write_index_multiple.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nstruct Foo {\n    type func new(x) = alloc(This) { .x };\n\n    operator []=(a,b,n) {\n        this.x = this.x * a + b * n;\n    }\n\n    operator[](n) {\n        return this.x - n;\n    }\n}\n\nfunc main() {\n    val f = Foo.new(5);\n    assert f[0] == 5;\n\n    f[3,4] = 5;\n    assert f[1] == 34;\n    assert f[0] == 35;\n    f[2,0] = 10;\n    assert f[0] == 70;\n    assert f[10] == 60;\n}\n"
  },
  {
    "path": "tests/write_list_index.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc main() {\n    val list = [1,2,3,4,5];\n    list[0] = list[4] + list[0];\n    val l0 = list[0];\n    assert l0 == 6;\n    val l1 = list[1];\n    assert l1 == 2;\n    list[1] = 3;\n    assert l1 == 2;\n    l1 = list[1];\n    assert l1 == 3;\n    val l2 = list[2];\n    assert l2 == 3;\n    val l3 = list[3];\n    assert l3 == 4;\n    val l4 = list[4];\n    assert l4 == 5;\n}\n"
  },
  {
    "path": "tests/writeattr.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc foo(x,y) {\n    return x + y + foo.n;\n}\n\nfunc main() {\n    writeattr(foo, \"n\", 5);\n    assert foo(3,4) == 12;\n    assert readattr(foo, \"n\") == 5;\n    assert foo.n == 5;\n\n    writeattr(foo, \"n\", 10);\n    assert foo(3,4) == 17;\n    assert readattr(foo, \"n\") == 10;\n    assert foo.n == 10;\n}\n"
  },
  {
    "path": "tests/xor.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nfunc boolean() {\n    assert (true ^ true) == false;\n    assert (true ^ false) == true;\n    assert (false ^ true) == true;\n    assert (false ^ false) == false;\n}\n\nfunc integer() {\n    val a =           0b00101110101011110001;\n    val b =           0b00010100001100011010;\n    assert (a ^ b) == 0b00111010100111101011;\n}\n\nfunc main() {\n    integer();\n    boolean();\n}\n"
  },
  {
    "path": "tests/xorshift.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nimport XorshiftRng from aria.rng.xorshift;\nimport Range from aria.range.range;\n\nfunc main() {\n    val rng = XorshiftRng.new();\n\n    # TODO: replace this with a proper verification, this is not exactly\n    # guaranteed - just very very likely\n    assert rng.next() != rng.next();\n    assert rng.next() != rng.next();\n    assert rng.next() != rng.next();\n\n    val die = Range.from(1).through(6).iterator().to_list();\n\n    for _ in Range.from(0).to(100) {\n        val random = rng.one_of(die);\n        assert random >= 1;\n        assert random <= 6;\n    }\n}\n"
  },
  {
    "path": "tree_check.sh",
    "content": "#!/usr/bin/env bash\nset -e\n\nSELF_DIR=\"$(dirname \"$(readlink -f \"${BASH_SOURCE[0]}\")\")\"\n\n# Runs some checks on the source tree, to make sure the source tree is well-formed.\n# This includes:\n#  - formatting of Rust code\n#  - no warnings from clippy\n#  - license markers in each source file\n\n# It is intended to be run in CI, but can also be run locally.\n\n${SELF_DIR}/add_license_marker.sh --check && \\\ncargo fmt --check && \\\ncargo clippy --no-deps\n"
  },
  {
    "path": "vm-lib/Cargo.toml",
    "content": "[package]\nname = \"vm-lib\"\nversion = \"0.9.20251222\"\nedition = \"2024\"\n\n[lib]\nname = \"haxby_vm\"\npath = \"src/lib.rs\"\n\n[dependencies]\npest = \"2.8.5\"\npest_derive = \"2.8.5\"\nparser-lib = { path = \"../parser-lib\" }\ncompiler-lib = { path = \"../compiler-lib\" }\nopcodes-lib = { path = \"../opcodes-lib\" }\nenum-as-inner = \"0.7.0\"\nthiserror = \"2.0.18\"\nlibloading = \"0.9.0\"\nlibc = \"0.2.180\"\nrustc_data_structures = \"0.1.2\"\n\n[dev-dependencies]\ncriterion = { version = \"0.8.2\" }\n\n[[bench]]\nname = \"control_flow\"\nharness = false"
  },
  {
    "path": "vm-lib/benches/control_flow.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::hint::black_box;\n\nuse aria_compiler::compile_from_source;\nuse aria_parser::ast::SourceBuffer;\nuse criterion::{Criterion, criterion_group, criterion_main};\nuse haxby_vm::haxby_eval;\n\nfn bench_aria_code_aux(bench_name: &str, src: &str, c: &mut Criterion) {\n    c.bench_function(&format!(\"{}/compile\", bench_name), |b| {\n        b.iter(|| {\n            let sb = SourceBuffer::stdin(src);\n            black_box(\n                compile_from_source(&sb, &Default::default()).expect(\"module did not compile\"),\n            );\n        })\n    });\n\n    let sb = SourceBuffer::stdin(src);\n\n    c.bench_function(&format!(\"{}/eval\", bench_name), |b| {\n        b.iter_batched(\n            || compile_from_source(&sb, &Default::default()).expect(\"module did not compile\"),\n            |module| black_box(haxby_eval(module, Default::default()).unwrap()),\n            criterion::BatchSize::SmallInput,\n        )\n    });\n}\n\nfn bench_if(c: &mut Criterion) {\n    const INPUT: &str = r#\"\n    func main() {\n        if true {\n\n        } else {\n\n        }\n        if false {\n\n        } else {\n\n        }\n    }\n    \"#;\n\n    bench_aria_code_aux(\"control_flow/if\", INPUT, c);\n}\n\nfn bench_for(c: &mut Criterion) {\n    const INPUT: &str = r#\"\n    func main() {\n        for i in Range.from(0).to(10) {\n            println(i);\n        }\n    }\n    \"#;\n\n    bench_aria_code_aux(\"control_flow/for\", INPUT, c);\n}\n\nfn bench_while(c: &mut Criterion) {\n    const INPUT: &str = r#\"\n    func main() {\n        val i = 0;\n        while i < 10 {\n            i = i + 1;\n        }\n    }\n    \"#;\n\n    bench_aria_code_aux(\"control_flow/while\", INPUT, c);\n}\n\nfn bench_empty_function_call(c: &mut Criterion) {\n    const INPUT: &str = r#\"\n    func foo() {}\n    func main() {\n        val i = 0;\n        while i < 10 {\n            foo();\n            i += 1;\n        }\n    }\n    \"#;\n\n    bench_aria_code_aux(\"control_flow/empty_function_call\", INPUT, c);\n}\n\nfn bench_list_read(c: &mut Criterion) {\n    const INPUT: &str = r#\"\n    func foo(_) {}\n    func main() {\n        val x = [1,2,3,4,5,6,7,8,9,10];\n        val i = 0;\n        while i < x.len() {\n            foo(x[i]);\n            i += 1;\n        }\n    }\n    \"#;\n\n    bench_aria_code_aux(\"control_flow/list_read\", INPUT, c);\n}\n\nfn bench_object_read(c: &mut Criterion) {\n    const INPUT: &str = r#\"\n    func foo(_) {}\n    func main() {\n        val x = Box(){\n            .a = 1,\n            .b = 2,\n            .c = 3,\n            .d = 4,\n            .e = 5,\n            .f = 6,\n            .g = 7,\n            .h = 8,\n            .i = 9,\n            .j = 10\n        };\n        foo(x.a);\n        foo(x.b);\n        foo(x.c);\n        foo(x.d);\n        foo(x.e);\n        foo(x.f);\n        foo(x.g);\n        foo(x.h);\n        foo(x.i);\n        foo(x.j);\n    }\n    \"#;\n\n    bench_aria_code_aux(\"control_flow/object_read\", INPUT, c);\n}\n\ncriterion_group!(\n    control_flow,\n    bench_if,\n    bench_for,\n    bench_while,\n    bench_empty_function_call,\n    bench_list_read,\n    bench_object_read,\n);\ncriterion_main!(control_flow);\n"
  },
  {
    "path": "vm-lib/src/arity.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\npub struct Arity {\n    pub required: u8,\n    pub optional: u8,\n}\n\nimpl Arity {\n    pub fn zero() -> Self {\n        Self {\n            required: 0,\n            optional: 0,\n        }\n    }\n\n    pub fn required(r: u8) -> Self {\n        Self {\n            required: r,\n            optional: 0,\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/alloc.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    arity::Arity,\n    builtins::VmGlobals,\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, kind::RuntimeValueType, object::Object,\n    },\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Alloc {}\nimpl BuiltinFunctionImpl for Alloc {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        use crate::runtime_value::rust_native_type::RustNativeValueKind as BVK;\n        let alloc_type = VmGlobals::extract_arg(frame, |x| x.as_type().cloned())?;\n\n        match alloc_type {\n            RuntimeValueType::RustNative(b) => {\n                let rv = match b.get_tag() {\n                    BVK::Boolean => RuntimeValue::Boolean(false.into()),\n                    BVK::Integer => RuntimeValue::Integer(0.into()),\n                    BVK::Float => RuntimeValue::Float(0.0.into()),\n                    BVK::List => RuntimeValue::List(crate::runtime_value::list::List::from(&[])),\n                    BVK::String => RuntimeValue::String(\"\".into()),\n                    BVK::Type => return Err(VmErrorReason::UnexpectedType.into()),\n                };\n                frame.stack.push(rv);\n            }\n            RuntimeValueType::Struct(s) => {\n                let obj = RuntimeValue::Object(Object::new(&s));\n                frame.stack.push(obj);\n            }\n            _ => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        }\n\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> Arity {\n        Arity {\n            required: 1,\n            optional: 0,\n        }\n    }\n\n    fn name(&self) -> &str {\n        \"alloc\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Alloc>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/arity.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::cell::OnceCell;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::vm_error::{VmError, VmErrorReason},\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl, object::Object},\n    symbol::{INTERNED_CASE_BOUNDED, INTERNED_CASE_VARARGS, INTERNED_OP_IMPL_CALL},\n    vm::RunloopExit,\n};\n\nstruct Cache {\n    arity_struct: crate::runtime_value::structure::Struct,\n    upper_bound_enum: crate::runtime_value::enumeration::Enum,\n    vararg_idx: usize,\n    bounded_idx: usize,\n}\n\n#[derive(Default)]\nstruct Arity {\n    cache: OnceCell<Cache>,\n}\nimpl Arity {\n    fn fill_in_cache(&self, vm: &mut crate::vm::VirtualMachine) -> Result<&Cache, VmError> {\n        if let Some(cache) = self.cache.get() {\n            Ok(cache)\n        } else {\n            let arity_mod = vm.find_imported_module(\"aria.core.arity\").ok_or_else(|| {\n                VmErrorReason::ImportNotAvailable(\n                    \"aria.core.arity\".to_owned(),\n                    \"module not found\".to_owned(),\n                )\n            })?;\n            let arity_struct = arity_mod.load_named_value(\"Arity\").ok_or_else(|| {\n                VmErrorReason::NoSuchIdentifier(\"aria.core.arity.Arity\".to_owned())\n            })?;\n            let arity_struct = arity_struct\n                .as_struct()\n                .ok_or(VmErrorReason::UnexpectedType)?;\n            let upper_bound_sym = vm\n                .globals\n                .intern_symbol(\"UpperBound\")\n                .expect(\"too many symbols interned\");\n            let upper_bound_enum = arity_struct\n                .load_named_value(&vm.globals, upper_bound_sym)\n                .ok_or_else(|| {\n                    VmErrorReason::NoSuchIdentifier(\"aria.core.arity.Arity.UpperBound\".to_owned())\n                })?;\n            let upper_bound_enum = upper_bound_enum\n                .as_enum()\n                .ok_or(VmErrorReason::UnexpectedType)?;\n\n            let vararg_idx = upper_bound_enum\n                .get_idx_of_case_by_symbol(&vm.globals, INTERNED_CASE_VARARGS)\n                .ok_or_else(|| VmErrorReason::NoSuchCase(\"Varargs\".to_owned()))?;\n\n            let bounded_idx = upper_bound_enum\n                .get_idx_of_case_by_symbol(&vm.globals, INTERNED_CASE_BOUNDED)\n                .ok_or_else(|| VmErrorReason::NoSuchCase(\"Bounded\".to_owned()))?;\n\n            let cache = Cache {\n                arity_struct: arity_struct.clone(),\n                upper_bound_enum: upper_bound_enum.clone(),\n                vararg_idx,\n                bounded_idx,\n            };\n\n            let _ = self.cache.set(cache);\n            Ok(self.cache.get().unwrap())\n        }\n    }\n}\n\nfn get_to_function_for_callable(\n    val: &RuntimeValue,\n    vm: &mut crate::vm::VirtualMachine,\n) -> Option<(crate::runtime_value::function::Function, bool)> {\n    if let Some(f) = val.as_function() {\n        Some((f.clone(), false))\n    } else if let Some(bf) = val.as_bound_function() {\n        Some((bf.func().clone(), true))\n    } else if let Ok(call) = val.read_attribute(INTERNED_OP_IMPL_CALL, &vm.globals) {\n        get_to_function_for_callable(&call, vm)\n    } else {\n        None\n    }\n}\n\nimpl BuiltinFunctionImpl for Arity {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let (f_this, has_receiver) =\n            VmGlobals::extract_arg(frame, |val| get_to_function_for_callable(&val, vm))?;\n        let arity_cache = self.fill_in_cache(vm)?;\n\n        let f_arity = f_this.arity();\n        let is_vararg = f_this.attribute().is_vararg();\n\n        let argc_offset = if has_receiver { 1 } else { 0 };\n\n        let upper_bound_value = if is_vararg {\n            arity_cache\n                .upper_bound_enum\n                .make_value(arity_cache.vararg_idx, None)\n        } else {\n            arity_cache.upper_bound_enum.make_value(\n                arity_cache.bounded_idx,\n                Some(RuntimeValue::Integer(\n                    ((f_arity.optional + f_arity.required - argc_offset) as i64).into(),\n                )),\n            )\n        }\n        .ok_or(VmErrorReason::UnexpectedType)?;\n\n        let upper_bound_value = RuntimeValue::EnumValue(upper_bound_value);\n\n        let lower_bound_value =\n            RuntimeValue::Integer(((f_arity.required - argc_offset) as i64).into());\n\n        let min_sym = vm\n            .globals\n            .intern_symbol(\"min\")\n            .expect(\"too many symbols interned\");\n        let max_sym = vm\n            .globals\n            .intern_symbol(\"max\")\n            .expect(\"too many symbols interned\");\n        let has_receiver_sym = vm\n            .globals\n            .intern_symbol(\"has_receiver\")\n            .expect(\"too many symbols interned\");\n\n        let arity_object = Object::new(&arity_cache.arity_struct)\n            .with_value(&mut vm.globals, min_sym, lower_bound_value)\n            .with_value(&mut vm.globals, max_sym, upper_bound_value)\n            .with_value(\n                &mut vm.globals,\n                has_receiver_sym,\n                RuntimeValue::Boolean(has_receiver.into()),\n            );\n\n        frame.stack.push(RuntimeValue::Object(arity_object));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity {\n            required: 1,\n            optional: 0,\n        }\n    }\n\n    fn name(&self) -> &str {\n        \"arity\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Arity>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/boolean.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::runtime_value::{\n    RuntimeValue, kind::RuntimeValueType, rust_native_type::RustNativeType,\n};\n\nuse super::VmGlobals;\n\npub(super) fn insert_boolean_builtins(builtins: &mut VmGlobals) {\n    let bool_builtin =\n        RustNativeType::new(crate::runtime_value::rust_native_type::RustNativeValueKind::Boolean);\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Bool,\n        RuntimeValueType::RustNative(bool_builtin),\n    );\n\n    builtins.insert(\"true\", RuntimeValue::Boolean(true.into()));\n    builtins.insert(\"false\", RuntimeValue::Boolean(false.into()));\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/cmdline_args.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct CmdlineArgs {}\nimpl BuiltinFunctionImpl for CmdlineArgs {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let args = vm\n            .options\n            .vm_args\n            .iter()\n            .map(|arg| RuntimeValue::String(arg.as_str().into()))\n            .collect::<Vec<_>>();\n        let args_list = RuntimeValue::List(crate::runtime_value::list::List::from(&args));\n        cur_frame.stack.push(args_list);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::zero()\n    }\n\n    fn name(&self) -> &str {\n        \"cmdline_arguments\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<CmdlineArgs>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/exit.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals, frame::Frame, runtime_value::function::BuiltinFunctionImpl,\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Exit {}\nimpl BuiltinFunctionImpl for Exit {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let code = VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?;\n        std::process::exit(*code.raw_value() as i32);\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"exit\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Exit>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/float.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::function_attribs::FUNC_IS_METHOD;\n\nuse crate::{\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, kind::RuntimeValueType,\n        rust_native_type::RustNativeType,\n    },\n    vm::RunloopExit,\n};\n\nuse super::VmGlobals;\n\n#[derive(Default)]\nstruct FpHash {}\nimpl BuiltinFunctionImpl for FpHash {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_float().cloned())?;\n        let hv = unsafe { std::mem::transmute_copy::<f64, i64>(this.raw_value()) };\n        frame.stack.push(RuntimeValue::Integer(hv.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"hash\"\n    }\n}\n\n#[derive(Default)]\nstruct FpFloor {}\nimpl BuiltinFunctionImpl for FpFloor {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_float().cloned())?;\n        let result = RuntimeValue::Float(this.raw_value().floor().into());\n        frame.stack.push(result);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"floor\"\n    }\n}\n\n#[derive(Default)]\nstruct FpCeil {}\nimpl BuiltinFunctionImpl for FpCeil {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_float().cloned())?;\n        let result = RuntimeValue::Float(this.raw_value().ceil().into());\n        frame.stack.push(result);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"ceil\"\n    }\n}\n\n#[derive(Default)]\nstruct FpInt {}\nimpl BuiltinFunctionImpl for FpInt {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_float().cloned())?;\n        let iv = *this.raw_value() as i64;\n        frame.stack.push(RuntimeValue::Integer(iv.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"int\"\n    }\n}\n\n#[derive(Default)]\nstruct FpPrettyprint {}\nimpl BuiltinFunctionImpl for FpPrettyprint {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_float().cloned())?;\n        let format_opt = if !frame.stack.is_empty() {\n            Some(VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?)\n        } else {\n            None\n        };\n\n        let result = if let Some(format_str) = format_opt {\n            let format = format_str.raw_value();\n            if format == \".E\" || format == \".e\" {\n                format!(\"{:e}\", this.raw_value())\n            } else if format.starts_with('.') && format.len() > 1 {\n                if let Ok(precision) = format[1..].parse::<usize>() {\n                    format!(\"{:.precision$}\", this.raw_value(), precision = precision)\n                } else {\n                    this.raw_value().to_string()\n                }\n            } else {\n                this.raw_value().to_string()\n            }\n        } else {\n            this.raw_value().to_string()\n        };\n\n        frame.stack.push(RuntimeValue::String(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity {\n            required: 1,\n            optional: 1,\n        }\n    }\n\n    fn name(&self) -> &str {\n        \"prettyprint\"\n    }\n}\n\npub(super) fn insert_float_builtins(builtins: &mut VmGlobals) {\n    let fp_builtin =\n        RustNativeType::new(crate::runtime_value::rust_native_type::RustNativeValueKind::Float);\n\n    fp_builtin.insert_builtin::<FpHash>(builtins);\n    fp_builtin.insert_builtin::<FpFloor>(builtins);\n    fp_builtin.insert_builtin::<FpCeil>(builtins);\n    fp_builtin.insert_builtin::<FpInt>(builtins);\n    fp_builtin.insert_builtin::<FpPrettyprint>(builtins);\n\n    let inf_sym = builtins\n        .intern_symbol(\"inf\")\n        .expect(\"too many symbols interned\");\n    let nan_sym = builtins\n        .intern_symbol(\"nan\")\n        .expect(\"too many symbols interned\");\n    let epsilon_sym = builtins\n        .intern_symbol(\"epsilon\")\n        .expect(\"too many symbols interned\");\n    fp_builtin.write(builtins, inf_sym, RuntimeValue::Float(f64::INFINITY.into()));\n    fp_builtin.write(builtins, nan_sym, RuntimeValue::Float(f64::NAN.into()));\n    fp_builtin.write(\n        builtins,\n        epsilon_sym,\n        RuntimeValue::Float(f64::EPSILON.into()),\n    );\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Float,\n        RuntimeValueType::RustNative(fp_builtin),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/getenv.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Getenv {}\nimpl BuiltinFunctionImpl for Getenv {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let var_name = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        match std::env::var(var_name.raw_value()).map(|s| RuntimeValue::String(s.into())) {\n            Ok(s) => match vm.globals.create_maybe_some(s) {\n                Ok(s) => {\n                    frame.stack.push(s);\n                    Ok(RunloopExit::Ok(()))\n                }\n                Err(e) => Err(e.into()),\n            },\n            Err(_) => match vm.globals.create_maybe_none() {\n                Ok(s) => {\n                    frame.stack.push(s);\n                    Ok(RunloopExit::Ok(()))\n                }\n                Err(e) => Err(e.into()),\n            },\n        }\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"getenv\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Getenv>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/hasattr.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct HasAttr {}\nimpl BuiltinFunctionImpl for HasAttr {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = frame.stack.pop();\n        let the_string = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        if let Some(symbol) = vm.globals.lookup_symbol(the_string.raw_value()) {\n            let has_attr = the_value.read_attribute(symbol, &vm.globals).is_ok();\n            frame.stack.push(RuntimeValue::Boolean(has_attr.into()));\n        } else {\n            frame.stack.push(RuntimeValue::Boolean(false.into()));\n        }\n\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"hasattr\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<HasAttr>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/integer.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse haxby_opcodes::function_attribs::FUNC_IS_METHOD;\n\nuse crate::{\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, kind::RuntimeValueType,\n        rust_native_type::RustNativeType,\n    },\n    vm::RunloopExit,\n};\n\nuse super::VmGlobals;\n\nfn int_format(n: i64, fmt: &str) -> String {\n    // Determine if format ends with 'x' or 'X' for hexadecimal formatting\n    let (base, digits_spec) = if let Some(stripped) = fmt.strip_suffix('x') {\n        (16, (stripped, false)) // lowercase hex\n    } else if let Some(stripped) = fmt.strip_suffix('X') {\n        (16, (stripped, true)) // uppercase hex\n    } else {\n        (10, (fmt, false)) // decimal\n    };\n\n    // Parse width from digits (if any), default to 0\n    let width = digits_spec.0.parse::<usize>().unwrap_or(0);\n    let uppercase = digits_spec.1;\n\n    if base == 16 {\n        // Format hex with padding and case\n        if uppercase {\n            format!(\"{n:0width$X}\")\n        } else {\n            format!(\"{n:0width$x}\")\n        }\n    } else {\n        // Format decimal with padding\n        format!(\"{n:0width$}\")\n    }\n}\n\n#[derive(Default)]\nstruct Prettyprint {}\nimpl BuiltinFunctionImpl for Prettyprint {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?;\n        let format_style = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        let output_string = int_format(*this.raw_value(), format_style.raw_value());\n        frame.stack.push(RuntimeValue::String(output_string.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"prettyprint\"\n    }\n}\n\npub(super) fn insert_integer_builtins(builtins: &mut VmGlobals) {\n    let int_builtin =\n        RustNativeType::new(crate::runtime_value::rust_native_type::RustNativeValueKind::Integer);\n\n    int_builtin.insert_builtin::<Prettyprint>(builtins);\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Int,\n        RuntimeValueType::RustNative(int_builtin),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::function_attribs::{FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\n\nuse crate::{\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, kind::RuntimeValueType, list::List,\n        rust_native_type::RustNativeType,\n    },\n    vm::RunloopExit,\n};\n\nuse super::VmGlobals;\n\n#[derive(Default)]\nstruct ListLen {}\nimpl BuiltinFunctionImpl for ListLen {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let len = this.len() as i64;\n        frame.stack.push(RuntimeValue::Integer(len.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"len\"\n    }\n}\n\n#[derive(Default)]\nstruct ListAppend {}\nimpl BuiltinFunctionImpl for ListAppend {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let the_value = frame.stack.pop();\n        this.append(the_value);\n        frame.stack.push(RuntimeValue::List(this));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"append\"\n    }\n}\n\n#[derive(Default)]\nstruct Drop {}\nimpl BuiltinFunctionImpl for Drop {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        if this.is_empty() {\n            Err(VmErrorReason::IndexOutOfBounds(0).into())\n        } else {\n            let the_value = this.get_at(this.len() - 1).unwrap();\n            this.pop();\n            frame.stack.push(the_value);\n            Ok(RunloopExit::Ok(()))\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"drop\"\n    }\n}\n\n#[derive(Default)]\nstruct GetAt {}\nimpl BuiltinFunctionImpl for GetAt {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let index = VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?;\n        let index = *index.raw_value() as usize;\n        match this.get_at(index) {\n            Some(v) => {\n                frame.stack.push(v);\n                Ok(RunloopExit::Ok(()))\n            }\n            None => Err(VmErrorReason::IndexOutOfBounds(index).into()),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_get_at\"\n    }\n}\n\n#[derive(Default)]\nstruct OpReadIndex {}\nimpl BuiltinFunctionImpl for OpReadIndex {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let index = *VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?.raw_value();\n        let index = if index < 0 {\n            index + this.len() as i64\n        } else {\n            index\n        } as usize;\n        match this.get_at(index) {\n            Some(v) => {\n                frame.stack.push(v);\n                Ok(RunloopExit::Ok(()))\n            }\n            None => Err(VmErrorReason::IndexOutOfBounds(index).into()),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_op_impl_read_index\"\n    }\n}\n\n#[derive(Default)]\nstruct SetAt {}\nimpl BuiltinFunctionImpl for SetAt {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let index = VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?;\n        let index = *index.raw_value() as usize;\n        let value = frame.stack.pop();\n        match this.set_at(index, value) {\n            Ok(_) => {\n                frame.stack.push(vm.globals.create_unit_object()?);\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => Err(e.into()),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"_set_at\"\n    }\n}\n\n#[derive(Default)]\nstruct OpWriteIndex {}\nimpl BuiltinFunctionImpl for OpWriteIndex {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_list().cloned())?;\n        let index = *VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?.raw_value();\n        let index = if index < 0 {\n            index + this.len() as i64\n        } else {\n            index\n        } as usize;\n        let value = frame.stack.pop();\n        match this.set_at(index, value) {\n            Ok(_) => {\n                frame.stack.push(vm.globals.create_unit_object()?);\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => Err(e.into()),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"_op_impl_write_index\"\n    }\n}\n\n#[derive(Default)]\nstruct NewWithCapacity {}\nimpl BuiltinFunctionImpl for NewWithCapacity {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let _ = frame.stack.pop(); // ignore List type, we know who we are\n        let capacity = *VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?.raw_value();\n        let capacity = if capacity < 0 { 0 } else { capacity } as usize;\n        let list = List::new_with_capacity(capacity);\n        frame.stack.push(RuntimeValue::List(list));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"new_with_capacity\"\n    }\n}\n\npub(super) fn insert_list_builtins(builtins: &mut VmGlobals) {\n    let list_builtin =\n        RustNativeType::new(crate::runtime_value::rust_native_type::RustNativeValueKind::List);\n\n    list_builtin.insert_builtin::<ListLen>(builtins);\n    list_builtin.insert_builtin::<ListAppend>(builtins);\n    list_builtin.insert_builtin::<Drop>(builtins);\n    list_builtin.insert_builtin::<GetAt>(builtins);\n    list_builtin.insert_builtin::<OpReadIndex>(builtins);\n    list_builtin.insert_builtin::<SetAt>(builtins);\n    list_builtin.insert_builtin::<OpWriteIndex>(builtins);\n    list_builtin.insert_builtin::<NewWithCapacity>(builtins);\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::List,\n        RuntimeValueType::RustNative(list_builtin),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/listattrs.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl, list::List},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct ListAttrs {}\nimpl BuiltinFunctionImpl for ListAttrs {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = frame.stack.pop();\n        let attrs = the_value.list_attributes(&vm.globals);\n        frame.stack.push(RuntimeValue::List(List::from(\n            &attrs\n                .iter()\n                .map(|x| RuntimeValue::String(x.clone().into()))\n                .collect::<Vec<_>>(),\n        )));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"listattrs\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<ListAttrs>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/maybe.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::runtime_value::{\n    enumeration::{Enum, EnumCase},\n    isa::IsaCheckable,\n    kind::RuntimeValueType,\n};\n\nuse super::VmGlobals;\n\npub(super) fn insert_maybe_builtins(builtins: &mut VmGlobals) {\n    let some_sym = builtins\n        .intern_symbol(\"Some\")\n        .expect(\"too many symbols interned\");\n    let none_sym = builtins\n        .intern_symbol(\"None\")\n        .expect(\"too many symbols interned\");\n    let maybe_enum = Enum::new_with_cases(\n        \"Maybe\",\n        &[\n            EnumCase {\n                name: some_sym,\n                payload_type: Some(IsaCheckable::any()),\n            },\n            EnumCase {\n                name: none_sym,\n                payload_type: None,\n            },\n        ],\n        builtins,\n    );\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Maybe,\n        RuntimeValueType::Enum(maybe_enum),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::rc::Rc;\n\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue,\n        function::{BuiltinFunctionImpl, Function},\n        kind::RuntimeValueType,\n        object::ObjectBox,\n    },\n    shape::Shapes,\n    symbol::Interner,\n};\n\nmod alloc;\nmod arity;\nmod boolean;\nmod cmdline_args;\nmod exit;\nmod float;\nmod getenv;\nmod hasattr;\nmod integer;\nmod list;\nmod listattrs;\nmod maybe;\npub mod native_iterator;\nmod now;\nmod prettyprint;\nmod print;\nmod println;\nmod readattr;\nmod readln;\nmod result;\npub(crate) mod runtime_error;\nmod setenv;\nmod sleep;\nmod string;\nmod system;\nmod typ;\nmod typeof_builtin;\nmod unimplemented;\nmod unit;\nmod writeattr;\n\n#[derive(Default)]\npub struct AriaBuiltinTypes {\n    types: Vec<RuntimeValueType>,\n}\n\nimpl AriaBuiltinTypes {\n    #[inline(always)]\n    pub fn register_builtin_type(&mut self, bt: RuntimeValueType) -> BuiltinTypeId {\n        self.types.push(bt);\n        let ty_id = u8::try_from(self.types.len() - 1).expect(\"too many builtin types registered\");\n        BuiltinTypeId::try_from(ty_id).expect(\"invalid builtin type id\")\n    }\n\n    #[inline(always)]\n    pub fn get_builtin_type(&self, id: BuiltinTypeId) -> RuntimeValueType {\n        self.types\n            .get(id as usize)\n            .expect(\"invalid builtin type id\")\n            .clone()\n    }\n}\n\npub struct VmGlobals {\n    values: Rc<ObjectBox>,\n    builtin_types: AriaBuiltinTypes,\n    interner: Interner,\n    pub(crate) shapes: Shapes,\n}\n\nimpl VmGlobals {\n    pub fn insert_builtin<T>(&mut self)\n    where\n        T: 'static + Default + BuiltinFunctionImpl,\n    {\n        let t = T::default();\n        let name = t.name().to_owned();\n        self.insert(&name, RuntimeValue::Function(Function::builtin_from(t)));\n    }\n\n    pub fn extract_arg<T, U>(frame: &mut Frame, f: T) -> crate::vm::ExecutionResult<U>\n    where\n        T: FnOnce(RuntimeValue) -> Option<U>,\n    {\n        let val = match frame.stack.try_pop() {\n            Some(v) => v,\n            None => {\n                return Err(VmErrorReason::EmptyStack.into());\n            }\n        };\n\n        match f(val) {\n            Some(v) => Ok(v),\n            None => Err(VmErrorReason::UnexpectedType.into()),\n        }\n    }\n\n    pub fn register_builtin_type(&mut self, id: BuiltinTypeId, ty: RuntimeValueType) {\n        let name = id.name();\n        let registered_id = self.builtin_types.register_builtin_type(ty.clone());\n        assert!(\n            id == registered_id,\n            \"Mismatched builtin type registration: expected {} [{}], got {} [{}]\",\n            id.to_u8(),\n            id.name(),\n            registered_id.to_u8(),\n            registered_id.name()\n        ); // catch mismatched registrations early\n        self.insert(name, RuntimeValue::Type(ty));\n    }\n}\n\nimpl Default for VmGlobals {\n    fn default() -> Self {\n        let mut this = Self {\n            values: Default::default(),\n            builtin_types: Default::default(),\n            interner: Default::default(),\n            shapes: Default::default(),\n        };\n\n        this.register_builtin_type(BuiltinTypeId::Any, RuntimeValueType::Any); // Most anything needs Any\n        this.register_builtin_type(BuiltinTypeId::Module, RuntimeValueType::Module);\n\n        unit::insert_unit_builtins(&mut this);\n        unimplemented::insert_unimplemented_builtins(&mut this);\n        maybe::insert_maybe_builtins(&mut this);\n        result::insert_result_builtins(&mut this);\n        integer::insert_integer_builtins(&mut this); // RuntimeError needs Integer\n        string::insert_string_builtins(&mut this); // and String\n        runtime_error::insert_runtime_error_builtins(&mut this);\n\n        // from here on out, any order is fine\n\n        alloc::insert_builtins(&mut this);\n        arity::insert_builtins(&mut this);\n        boolean::insert_boolean_builtins(&mut this);\n        cmdline_args::insert_builtins(&mut this);\n        exit::insert_builtins(&mut this);\n        float::insert_float_builtins(&mut this);\n        getenv::insert_builtins(&mut this);\n        hasattr::insert_builtins(&mut this);\n        list::insert_list_builtins(&mut this);\n        listattrs::insert_builtins(&mut this);\n        now::insert_builtins(&mut this);\n        prettyprint::insert_builtins(&mut this);\n        print::insert_builtins(&mut this);\n        println::insert_builtins(&mut this);\n        readattr::insert_builtins(&mut this);\n        readln::insert_builtins(&mut this);\n        setenv::insert_builtins(&mut this);\n        sleep::insert_builtins(&mut this);\n        system::insert_builtins(&mut this);\n        typ::insert_type_builtins(&mut this);\n        typeof_builtin::insert_builtins(&mut this);\n        writeattr::insert_builtins(&mut this);\n\n        this\n    }\n}\n\nimpl VmGlobals {\n    pub fn intern_symbol(&mut self, s: &str) -> Result<crate::symbol::Symbol, VmErrorReason> {\n        self.interner.intern(s).map_err(|e| match e {\n            crate::symbol::InternError::TooManySymbols => VmErrorReason::TooManyInternedSymbols,\n        })\n    }\n\n    pub fn lookup_symbol(&self, s: &str) -> Option<crate::symbol::Symbol> {\n        self.interner.lookup(s)\n    }\n\n    pub fn resolve_symbol(&self, sym: crate::symbol::Symbol) -> Option<&str> {\n        self.interner.resolve(sym)\n    }\n\n    pub fn load_named_value(&self, name: &str) -> Option<RuntimeValue> {\n        let sym = self.lookup_symbol(name)?;\n        self.values.read(self, sym)\n    }\n\n    pub fn insert(&mut self, name: &str, val: RuntimeValue) {\n        let sym = self.intern_symbol(name).expect(\"too many symbols interned\");\n        let values = Rc::clone(&self.values);\n        if values.contains(self, sym) {\n            panic!(\"duplicate builtin {name}\");\n        }\n\n        values.write(self, sym, val);\n    }\n\n    #[deprecated(note = \"use get_builtin_type_by_id instead\")]\n    pub fn get_builtin_type_by_name(&self, name: &str) -> Option<RuntimeValueType> {\n        if let Some(bv) = self.load_named_value(name) {\n            bv.as_type().cloned()\n        } else {\n            None\n        }\n    }\n\n    pub fn get_builtin_type_by_id(&self, bt_id: BuiltinTypeId) -> RuntimeValueType {\n        self.builtin_types.get_builtin_type(bt_id)\n    }\n}\n\nimpl VmGlobals {\n    pub fn create_maybe_some(&self, x: RuntimeValue) -> Result<RuntimeValue, VmErrorReason> {\n        let rt_maybe = self.get_builtin_type_by_id(BuiltinTypeId::Maybe);\n        let rt_maybe_enum = rt_maybe.as_enum().ok_or(VmErrorReason::UnexpectedType)?;\n\n        let some_idx: usize = 0usize;\n\n        let rv = rt_maybe_enum\n            .make_value(some_idx, Some(x))\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        Ok(RuntimeValue::EnumValue(rv))\n    }\n\n    pub fn create_result_ok(&self, x: RuntimeValue) -> Result<RuntimeValue, VmErrorReason> {\n        let rt_result = self.get_builtin_type_by_id(BuiltinTypeId::Result);\n        let rt_result_enum = rt_result.as_enum().ok_or(VmErrorReason::UnexpectedType)?;\n\n        let ok_idx = 0usize;\n\n        let rv = rt_result_enum\n            .make_value(ok_idx, Some(x))\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        Ok(RuntimeValue::EnumValue(rv))\n    }\n\n    pub fn create_maybe_none(&self) -> Result<RuntimeValue, VmErrorReason> {\n        let rt_maybe = self.get_builtin_type_by_id(BuiltinTypeId::Maybe);\n        let rt_maybe_enum = rt_maybe.as_enum().ok_or(VmErrorReason::UnexpectedType)?;\n\n        let none_idx = 1usize;\n\n        let rv = rt_maybe_enum\n            .make_value(none_idx, None)\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        Ok(RuntimeValue::EnumValue(rv))\n    }\n\n    pub fn create_result_err(&self, x: RuntimeValue) -> Result<RuntimeValue, VmErrorReason> {\n        let rt_result = self.get_builtin_type_by_id(BuiltinTypeId::Result);\n        let rt_result_enum = rt_result.as_enum().ok_or(VmErrorReason::UnexpectedType)?;\n\n        let err_idx = 1usize;\n\n        let rv = rt_result_enum\n            .make_value(err_idx, Some(x))\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        Ok(RuntimeValue::EnumValue(rv))\n    }\n\n    pub fn create_unit_object(&self) -> Result<RuntimeValue, VmErrorReason> {\n        let rt_unit = self.get_builtin_type_by_id(BuiltinTypeId::Unit);\n        let rt_unit_enum = rt_unit.as_enum().ok_or(VmErrorReason::UnexpectedType)?;\n\n        let unit_idx = 0usize;\n\n        let rv = rt_unit_enum\n            .make_value(unit_idx, None)\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        Ok(RuntimeValue::EnumValue(rv))\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/native_iterator.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::{cell::RefCell, rc::Rc};\n\nuse haxby_opcodes::function_attribs::FUNC_IS_METHOD;\n\nuse crate::{\n    arity::Arity,\n    builtins::VmGlobals,\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue,\n        function::{BuiltinFunctionImpl, Function},\n        object::Object,\n        opaque::OpaqueValue,\n        structure::Struct,\n    },\n    symbol::{INTERNED_ATTR_IMPL, INTERNED_ATTR_NEXT},\n    vm::RunloopExit,\n};\n\npub trait AriaNativeIterator {\n    type Item;\n\n    fn next(&mut self, _: &mut crate::vm::VirtualMachine) -> Option<Self::Item> {\n        None\n    }\n}\n\nstruct EmptyIterator {}\nimpl AriaNativeIterator for EmptyIterator {\n    type Item = RuntimeValue;\n}\n\npub struct NativeIteratorImpl {\n    iter: Rc<RefCell<dyn AriaNativeIterator<Item = RuntimeValue>>>,\n}\n\nimpl NativeIteratorImpl {\n    pub fn new<T>(iter: T) -> Self\n    where\n        T: AriaNativeIterator<Item = RuntimeValue> + 'static,\n    {\n        Self {\n            iter: Rc::new(RefCell::new(iter)),\n        }\n    }\n\n    pub fn empty() -> Self {\n        Self::new(EmptyIterator {})\n    }\n}\n\nimpl AriaNativeIterator for NativeIteratorImpl {\n    type Item = RuntimeValue;\n\n    fn next(&mut self, vm: &mut crate::vm::VirtualMachine) -> Option<Self::Item> {\n        self.iter.borrow_mut().next(vm)\n    }\n}\n\n#[derive(Default)]\nstruct Next {}\nimpl BuiltinFunctionImpl for Next {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let aria_this = VmGlobals::extract_arg(frame, |x: RuntimeValue| x.as_object().cloned())?;\n\n        let impl_sym = INTERNED_ATTR_IMPL;\n\n        let iterator_impl = aria_this\n            .read(&vm.globals, impl_sym)\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n        let rust_native_iter = iterator_impl\n            .as_opaque_concrete::<RefCell<NativeIteratorImpl>>()\n            .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n        if let Some(next) = rust_native_iter.borrow_mut().next(vm) {\n            frame.stack.push(vm.globals.create_maybe_some(next)?);\n        } else {\n            frame.stack.push(vm.globals.create_maybe_none()?);\n        }\n\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> Arity {\n        Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"next\"\n    }\n}\n\npub fn create_iterator_struct(\n    iter_struct: &Struct,\n    imp: NativeIteratorImpl,\n    builtins: &mut VmGlobals,\n) -> RuntimeValue {\n    let obj = RuntimeValue::Object(Object::new(iter_struct));\n    let impl_attrib = OpaqueValue::new(RefCell::new(imp));\n    obj.write_attribute(\n        INTERNED_ATTR_IMPL,\n        RuntimeValue::Opaque(impl_attrib),\n        builtins,\n    )\n    .expect(\"failed to write iterator impl\");\n    let next = Function::new_builtin::<Next>();\n    let bound_next = obj.bind(next);\n    obj.write_attribute(INTERNED_ATTR_NEXT, bound_next, builtins)\n        .expect(\"failed to write iterator next\");\n    obj\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/now.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Now {}\nimpl BuiltinFunctionImpl for Now {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let now = std::time::SystemTime::now()\n            .duration_since(std::time::UNIX_EPOCH)\n            .expect(\"before the epoch\")\n            .as_millis() as i64;\n        cur_frame.stack.push(RuntimeValue::Integer(now.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::zero()\n    }\n\n    fn name(&self) -> &str {\n        \"now\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Now>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/prettyprint.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Prettyprint {}\nimpl BuiltinFunctionImpl for Prettyprint {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = cur_frame.stack.pop();\n        let pp = the_value.prettyprint(cur_frame, vm);\n        cur_frame.stack.push(RuntimeValue::String(pp.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"prettyprint\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Prettyprint>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/print.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals, frame::Frame, runtime_value::function::BuiltinFunctionImpl,\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Print {}\nimpl BuiltinFunctionImpl for Print {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = cur_frame.stack.pop();\n        let fmt = the_value.prettyprint(cur_frame, vm);\n        let mut console = vm.console().borrow_mut();\n        assert!(console.print(&fmt).is_ok());\n\n        cur_frame.stack.push(vm.globals.create_unit_object()?);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"print\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Print>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/println.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals, frame::Frame, runtime_value::function::BuiltinFunctionImpl,\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Println {}\nimpl BuiltinFunctionImpl for Println {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        if let Some(the_value) = cur_frame.stack.try_pop() {\n            let fmt = the_value.prettyprint(cur_frame, vm);\n            assert!(vm.console().borrow_mut().println(&fmt).is_ok());\n        } else {\n            assert!(vm.console().borrow_mut().println(\"\").is_ok());\n        }\n\n        cur_frame.stack.push(vm.globals.create_unit_object()?);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity {\n            required: 0,\n            optional: 1,\n        }\n    }\n\n    fn name(&self) -> &str {\n        \"println\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Println>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/readattr.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals, error::vm_error::VmErrorReason, frame::Frame,\n    runtime_value::function::BuiltinFunctionImpl, vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct ReadAttr {}\nimpl BuiltinFunctionImpl for ReadAttr {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = frame.stack.pop();\n        let the_string = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        if let Some(symbol) = vm.globals.lookup_symbol(the_string.raw_value())\n            && let Ok(the_attr) = the_value.read_attribute(symbol, &vm.globals)\n        {\n            frame.stack.push(the_attr);\n            Ok(RunloopExit::Ok(()))\n        } else {\n            Err(VmErrorReason::NoSuchIdentifier(the_string.raw_value().to_owned()).into())\n        }\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"readattr\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<ReadAttr>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/readln.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::io::Write;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Readln {}\nimpl BuiltinFunctionImpl for Readln {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = cur_frame.stack.pop();\n        let the_value = the_value.prettyprint(cur_frame, vm);\n        let _ = std::io::stdout().write(the_value.as_bytes());\n        let _ = std::io::stdout().flush();\n\n        let mut input = String::new();\n        let result = std::io::stdin().read_line(&mut input);\n        match result {\n            Ok(_) => {\n                let input = input.trim();\n                cur_frame.stack.push(RuntimeValue::String(input.into()));\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => Err(VmErrorReason::OperationFailed(e.to_string()).into()),\n        }\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"readln\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Readln>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/result.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::runtime_value::{\n    enumeration::{Enum, EnumCase},\n    isa::IsaCheckable,\n    kind::RuntimeValueType,\n};\n\nuse super::VmGlobals;\n\npub(super) fn insert_result_builtins(builtins: &mut VmGlobals) {\n    let ok_sym = builtins\n        .intern_symbol(\"Ok\")\n        .expect(\"too many symbols interned\");\n    let err_sym = builtins\n        .intern_symbol(\"Err\")\n        .expect(\"too many symbols interned\");\n    let result_enum = Enum::new_with_cases(\n        \"Result\",\n        &[\n            EnumCase {\n                name: ok_sym,\n                payload_type: Some(IsaCheckable::any()),\n            },\n            EnumCase {\n                name: err_sym,\n                payload_type: Some(IsaCheckable::any()),\n            },\n        ],\n        builtins,\n    );\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Result,\n        RuntimeValueType::Enum(result_enum),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/runtime_error.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{\n    runtime_value::{\n        RuntimeValue,\n        enumeration::{Enum, EnumCase},\n        isa::IsaCheckable,\n        kind::RuntimeValueType,\n        structure::Struct,\n    },\n    symbol::INTERNED_ATTR_ARGC_MISMATCH,\n};\n\nuse super::VmGlobals;\n\npub const RUNTIME_ERR_CASE_DIVISION_BY_ZERO_IDX: usize = 0;\npub const RUNTIME_ERR_CASE_ENUM_WITHOUT_PAYLOAD_IDX: usize = 1;\npub const RUNTIME_ERR_CASE_INDEX_OUT_OF_BOUNDS_IDX: usize = 2;\npub const RUNTIME_ERR_CASE_MISMATCHED_ARGC_IDX: usize = 3;\npub const RUNTIME_ERR_CASE_NO_SUCH_CASE_IDX: usize = 4;\npub const RUNTIME_ERR_CASE_NO_SUCH_IDENTIFIER_IDX: usize = 5;\npub const RUNTIME_ERR_CASE_OPERATION_FAILED_IDX: usize = 6;\npub const RUNTIME_ERR_CASE_UNEXPECTED_TYPE_IDX: usize = 7;\n\npub(super) fn insert_runtime_error_builtins(builtins: &mut VmGlobals) {\n    let argc_mismatch = Struct::new(\"ArgcMismatch\");\n    let int = builtins.get_builtin_type_by_id(BuiltinTypeId::Int);\n    let str = builtins.get_builtin_type_by_id(BuiltinTypeId::String);\n    let division_by_zero_sym = builtins\n        .intern_symbol(\"DivisionByZero\")\n        .expect(\"too many symbols interned\");\n    let enum_without_payload_sym = builtins\n        .intern_symbol(\"EnumWithoutPayload\")\n        .expect(\"too many symbols interned\");\n    let index_out_of_bounds_sym = builtins\n        .intern_symbol(\"IndexOutOfBounds\")\n        .expect(\"too many symbols interned\");\n    let mismatched_argc_sym = builtins\n        .intern_symbol(\"MismatchedArgumentCount\")\n        .expect(\"too many symbols interned\");\n    let no_such_case_sym = builtins\n        .intern_symbol(\"NoSuchCase\")\n        .expect(\"too many symbols interned\");\n    let no_such_identifier_sym = builtins\n        .intern_symbol(\"NoSuchIdentifier\")\n        .expect(\"too many symbols interned\");\n    let operation_failed_sym = builtins\n        .intern_symbol(\"OperationFailed\")\n        .expect(\"too many symbols interned\");\n    let unexpected_type_sym = builtins\n        .intern_symbol(\"UnexpectedType\")\n        .expect(\"too many symbols interned\");\n\n    let rt_err_enum = RuntimeValue::Type(RuntimeValueType::Enum(Enum::new_with_cases(\n        \"RuntimeError\",\n        &[\n            EnumCase {\n                name: division_by_zero_sym,\n                payload_type: None,\n            },\n            EnumCase {\n                name: enum_without_payload_sym,\n                payload_type: None,\n            },\n            EnumCase {\n                name: index_out_of_bounds_sym,\n                payload_type: Some(IsaCheckable::Type(int.clone())),\n            },\n            EnumCase {\n                name: mismatched_argc_sym,\n                payload_type: Some(IsaCheckable::Type(RuntimeValueType::Struct(\n                    argc_mismatch.clone(),\n                ))),\n            },\n            EnumCase {\n                name: no_such_case_sym,\n                payload_type: Some(IsaCheckable::Type(str.clone())),\n            },\n            EnumCase {\n                name: no_such_identifier_sym,\n                payload_type: Some(IsaCheckable::Type(str.clone())),\n            },\n            EnumCase {\n                name: operation_failed_sym,\n                payload_type: Some(IsaCheckable::Type(str.clone())),\n            },\n            EnumCase {\n                name: unexpected_type_sym,\n                payload_type: None,\n            },\n        ],\n        builtins,\n    )));\n\n    let _ = rt_err_enum.write_attribute(\n        INTERNED_ATTR_ARGC_MISMATCH,\n        RuntimeValue::Type(RuntimeValueType::Struct(argc_mismatch)),\n        builtins,\n    );\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::RuntimeError,\n        rt_err_enum\n            .as_type()\n            .expect(\"RuntimeError is a type\")\n            .clone(),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/setenv.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals, error::vm_error::VmErrorReason, frame::Frame,\n    runtime_value::function::BuiltinFunctionImpl, vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Setenv {}\nimpl BuiltinFunctionImpl for Setenv {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let var_name = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        let var_value = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        if var_name.is_empty() || var_value.is_empty() {\n            return Err(VmErrorReason::OperationFailed(\"empty key or value\".into()).into());\n        }\n        if var_name.contains(\"=\") || var_value.contains(\"=\") {\n            return Err(VmErrorReason::OperationFailed(\n                \"key or value contains invalid character '='\".into(),\n            )\n            .into());\n        }\n        unsafe {\n            std::env::set_var(var_name.raw_value(), var_value.raw_value());\n        }\n        frame.stack.push(vm.globals.create_unit_object()?);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"setenv\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Setenv>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/sleep.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::time::Duration;\n\nuse super::VmGlobals;\nuse crate::{\n    error::vm_error::VmErrorReason, frame::Frame, runtime_value::function::BuiltinFunctionImpl,\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Sleep {}\nimpl BuiltinFunctionImpl for Sleep {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let duration = *VmGlobals::extract_arg(cur_frame, |x| x.as_integer().cloned())?.raw_value();\n        if duration >= 0 {\n            std::thread::sleep(Duration::from_millis(duration as u64));\n        } else {\n            return Err(\n                VmErrorReason::OperationFailed(\"cannot sleep < 0 milliseconds\".to_owned()).into(),\n            );\n        }\n\n        cur_frame.stack.push(vm.globals.create_unit_object()?);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"sleep_ms\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Sleep>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/string.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse haxby_opcodes::function_attribs::{FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE};\n\nuse crate::{\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{\n        RuntimeValue, function::BuiltinFunctionImpl, kind::RuntimeValueType, list::List,\n        rust_native_type::RustNativeType,\n    },\n    vm::RunloopExit,\n};\n\nuse super::VmGlobals;\n\n#[derive(Default)]\nstruct StringLen {}\nimpl BuiltinFunctionImpl for StringLen {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = frame.stack.pop();\n        if let Some(s) = the_value.as_string() {\n            let len = s.len() as i64;\n            frame.stack.push(RuntimeValue::Integer(len.into()));\n            Ok(RunloopExit::Ok(()))\n        } else {\n            Err(VmErrorReason::UnexpectedType.into())\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"len\"\n    }\n}\n\n#[derive(Default)]\nstruct StringHasPrefix {}\nimpl BuiltinFunctionImpl for StringHasPrefix {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let prefix = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let result = this.raw_value().starts_with(prefix.raw_value());\n        frame.stack.push(RuntimeValue::Boolean(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"has_prefix\"\n    }\n}\n\n#[derive(Default)]\nstruct StringHasSuffix {}\nimpl BuiltinFunctionImpl for StringHasSuffix {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let suffix = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let result = this.raw_value().ends_with(suffix.raw_value());\n        frame.stack.push(RuntimeValue::Boolean(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"has_suffix\"\n    }\n}\n\n#[derive(Default)]\nstruct StringReplace {}\nimpl BuiltinFunctionImpl for StringReplace {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let current = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let wanted = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let result = this\n            .raw_value()\n            .replace(current.raw_value(), wanted.raw_value());\n        frame.stack.push(RuntimeValue::String(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"replace\"\n    }\n}\n\n#[derive(Default)]\nstruct StringSplit {}\nimpl BuiltinFunctionImpl for StringSplit {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let marker = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let result = this\n            .raw_value()\n            .split(marker.raw_value())\n            .map(|x| RuntimeValue::String(x.to_owned().into()))\n            .collect::<Vec<_>>();\n        frame.stack.push(RuntimeValue::List(List::from(&result)));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"split\"\n    }\n}\n\n#[derive(Default)]\nstruct StringChars {}\nimpl BuiltinFunctionImpl for StringChars {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        let ret = List::default();\n        this.raw_value()\n            .chars()\n            .map(|c| RuntimeValue::String(c.to_string().into()))\n            .for_each(|rv| ret.append(rv));\n\n        frame.stack.push(RuntimeValue::List(ret));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"chars\"\n    }\n}\n\n#[derive(Default)]\nstruct StringBytes {}\nimpl BuiltinFunctionImpl for StringBytes {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        let ret = List::default();\n        this.raw_value()\n            .bytes()\n            .map(|c| RuntimeValue::Integer((c as i64).into()))\n            .for_each(|rv| ret.append(rv));\n\n        frame.stack.push(RuntimeValue::List(ret));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"bytes\"\n    }\n}\n\n#[derive(Default)]\nstruct FromBytes {}\nimpl BuiltinFunctionImpl for FromBytes {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this_str_type = match frame\n            .stack\n            .pop_if(|x| RuntimeValue::as_rust_native(&x).cloned())\n        {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let list = match frame.stack.pop_if(|x| RuntimeValue::as_list(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n        let mut bytes = vec![];\n        for i in 0..list.len() {\n            let item = list.get_at(i).expect(\"invalid list\");\n            if let Some(byte) = item.as_integer() {\n                bytes.push(*byte.raw_value() as u8);\n            } else {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        }\n        let dest = match String::from_utf8(bytes) {\n            Ok(s) => s,\n            Err(_) => {\n                let msg_sym = vm\n                    .globals\n                    .intern_symbol(\"msg\")\n                    .expect(\"too many symbols interned\");\n                let encoding_err_sym = vm\n                    .globals\n                    .intern_symbol(\"EncodingError\")\n                    .expect(\"too many symbols interned\");\n                let encoding_err_rv = this_str_type\n                    .read(&vm.globals, encoding_err_sym)\n                    .ok_or_else(|| VmErrorReason::NoSuchIdentifier(\"EncodingError\".to_owned()))?;\n\n                let encoding_err_struct = encoding_err_rv\n                    .as_struct()\n                    .ok_or(VmErrorReason::UnexpectedVmState)?;\n\n                return Ok(RunloopExit::throw_struct(\n                    encoding_err_struct,\n                    &[(msg_sym, RuntimeValue::String(\"invalid utf8\".into()))],\n                    &mut vm.globals,\n                ));\n            }\n        };\n\n        frame.stack.push(RuntimeValue::String(dest.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD | METHOD_ATTRIBUTE_TYPE\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"new_with_bytes\"\n    }\n}\n\n#[derive(Default)]\nstruct ToNumericEncoding {}\nimpl BuiltinFunctionImpl for ToNumericEncoding {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        if let Some(char) = this.raw_value().chars().next() {\n            let char = char as i64;\n            frame.stack.push(RuntimeValue::Integer(char.into()));\n            Ok(RunloopExit::Ok(()))\n        } else {\n            Err(VmErrorReason::UnexpectedType.into())\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"encoding\"\n    }\n}\n\n#[derive(Default)]\nstruct TrimHead {}\nimpl BuiltinFunctionImpl for TrimHead {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        let result = this.raw_value().trim_start().to_string();\n        frame.stack.push(RuntimeValue::String(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"trim_head\"\n    }\n}\n\n#[derive(Default)]\nstruct TrimTail {}\nimpl BuiltinFunctionImpl for TrimTail {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        let result = this.raw_value().trim_end().to_string();\n        frame.stack.push(RuntimeValue::String(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"trim_tail\"\n    }\n}\n\n#[derive(Default)]\nstruct Uppercase {}\nimpl BuiltinFunctionImpl for Uppercase {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        let result = this.raw_value().to_uppercase();\n        frame.stack.push(RuntimeValue::String(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"uppercase\"\n    }\n}\n\n#[derive(Default)]\nstruct Lowercase {}\nimpl BuiltinFunctionImpl for Lowercase {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = match frame.stack.pop_if(|x| RuntimeValue::as_string(&x).cloned()) {\n            Some(x) => x,\n            None => {\n                return Err(VmErrorReason::UnexpectedType.into());\n            }\n        };\n\n        let result = this.raw_value().to_lowercase();\n        frame.stack.push(RuntimeValue::String(result.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"lowercase\"\n    }\n}\n\n#[derive(Default)]\nstruct Contains {}\nimpl BuiltinFunctionImpl for Contains {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |a| a.as_string().cloned())?;\n        let that = VmGlobals::extract_arg(frame, |a| a.as_string().cloned())?;\n\n        let contains = this.raw_value().contains(that.raw_value());\n\n        frame.stack.push(RuntimeValue::Boolean(contains.into()));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"contains\"\n    }\n}\n\n#[derive(Default)]\nstruct GetAt {}\nimpl BuiltinFunctionImpl for GetAt {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        _: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let this = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        let index = VmGlobals::extract_arg(frame, |x| x.as_integer().cloned())?;\n        let index = *index.raw_value() as usize;\n        match this.get_at(index) {\n            Some(v) => {\n                frame.stack.push(v);\n                Ok(RunloopExit::Ok(()))\n            }\n            None => Err(VmErrorReason::IndexOutOfBounds(index).into()),\n        }\n    }\n\n    fn attrib_byte(&self) -> u8 {\n        FUNC_IS_METHOD\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(2)\n    }\n\n    fn name(&self) -> &str {\n        \"_get_at\"\n    }\n}\n\npub(super) fn insert_string_builtins(builtins: &mut VmGlobals) {\n    let string_builtin =\n        RustNativeType::new(crate::runtime_value::rust_native_type::RustNativeValueKind::String);\n\n    string_builtin.insert_builtin::<StringLen>(builtins);\n    string_builtin.insert_builtin::<StringHasPrefix>(builtins);\n    string_builtin.insert_builtin::<StringHasSuffix>(builtins);\n    string_builtin.insert_builtin::<StringReplace>(builtins);\n    string_builtin.insert_builtin::<StringSplit>(builtins);\n    string_builtin.insert_builtin::<StringChars>(builtins);\n    string_builtin.insert_builtin::<StringBytes>(builtins);\n    string_builtin.insert_builtin::<ToNumericEncoding>(builtins);\n    string_builtin.insert_builtin::<FromBytes>(builtins);\n    string_builtin.insert_builtin::<TrimHead>(builtins);\n    string_builtin.insert_builtin::<TrimTail>(builtins);\n    string_builtin.insert_builtin::<Uppercase>(builtins);\n    string_builtin.insert_builtin::<Lowercase>(builtins);\n    string_builtin.insert_builtin::<Contains>(builtins);\n    string_builtin.insert_builtin::<GetAt>(builtins);\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::String,\n        RuntimeValueType::RustNative(string_builtin),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/system.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse super::VmGlobals;\nuse crate::{\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl, integer::IntegerValue},\n    symbol::{INTERNED_ATTR_STDERR, INTERNED_ATTR_STDOUT},\n    vm::RunloopExit,\n};\nuse std::process::Command;\n\nfn get_shell_path() -> String {\n    // it's not like Aria is tested on Windows, but let's at least pretend to be nice\n    if cfg!(target_os = \"windows\") {\n        return std::env::var(\"COMSPEC\").unwrap_or_else(|_| \"cmd.exe\".to_string());\n    }\n    std::env::var(\"SHELL\").unwrap_or_else(|_| \"/bin/sh\".to_string())\n}\n\n#[derive(Default)]\nstruct System {}\nimpl BuiltinFunctionImpl for System {\n    fn eval(\n        &self,\n        cur_frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let command = VmGlobals::extract_arg(cur_frame, |x| x.as_string().cloned())?;\n\n        let output = Command::new(get_shell_path())\n            .arg(\"-c\")\n            .arg(command.raw_value())\n            .output();\n\n        match output {\n            Ok(output) => {\n                let result = RuntimeValue::Integer(IntegerValue::from(\n                    output.status.code().unwrap_or(-1) as i64,\n                ));\n                let _ = result.write_attribute(\n                    INTERNED_ATTR_STDOUT,\n                    RuntimeValue::String(\n                        String::from_utf8_lossy(&output.stdout).to_string().into(),\n                    ),\n                    &mut vm.globals,\n                );\n                let _ = result.write_attribute(\n                    INTERNED_ATTR_STDERR,\n                    RuntimeValue::String(\n                        String::from_utf8_lossy(&output.stderr).to_string().into(),\n                    ),\n                    &mut vm.globals,\n                );\n                cur_frame.stack.push(result);\n                Ok(RunloopExit::Ok(()))\n            }\n            Err(e) => Err(VmErrorReason::OperationFailed(e.to_string()).into()),\n        }\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"system\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<System>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/test_exit.aria",
    "content": "# SPDX-License-Identifier: Apache-2.0\nexit(42);\n"
  },
  {
    "path": "vm-lib/src/builtins/typ.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::runtime_value::{kind::RuntimeValueType, rust_native_type::RustNativeType};\n\nuse super::VmGlobals;\n\npub(super) fn insert_type_builtins(builtins: &mut VmGlobals) {\n    let type_builtin =\n        RustNativeType::new(crate::runtime_value::rust_native_type::RustNativeValueKind::Type);\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Type,\n        RuntimeValueType::RustNative(type_builtin),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/typeof_builtin.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_value::{RuntimeValue, function::BuiltinFunctionImpl, kind::RuntimeValueType},\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct Typeof {}\nimpl BuiltinFunctionImpl for Typeof {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_value = frame.stack.pop();\n        let the_type = RuntimeValueType::get_type(&the_value, &vm.globals);\n        frame.stack.push(RuntimeValue::Type(the_type));\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(1)\n    }\n\n    fn name(&self) -> &str {\n        \"typeof\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<Typeof>();\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/unimplemented.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::runtime_value::{kind::RuntimeValueType, structure::Struct};\n\nuse super::VmGlobals;\n\npub(super) fn insert_unimplemented_builtins(builtins: &mut VmGlobals) {\n    let unimplemented_struct = Struct::new(\"Unimplemented\");\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Unimplemented,\n        RuntimeValueType::Struct(unimplemented_struct.clone()),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/unit.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::runtime_value::{\n    enumeration::{Enum, EnumCase},\n    kind::RuntimeValueType,\n};\n\nuse super::VmGlobals;\n\npub(super) fn insert_unit_builtins(builtins: &mut VmGlobals) {\n    let unit_sym = builtins\n        .intern_symbol(\"unit\")\n        .expect(\"too many symbols interned\");\n    let unit_enum = Enum::new_with_cases(\n        \"Unit\",\n        &[EnumCase {\n            name: unit_sym,\n            payload_type: None,\n        }],\n        builtins,\n    );\n\n    builtins.register_builtin_type(\n        haxby_opcodes::BuiltinTypeId::Unit,\n        RuntimeValueType::Enum(unit_enum.clone()),\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/builtins/writeattr.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::{\n    builtins::VmGlobals, frame::Frame, runtime_value::function::BuiltinFunctionImpl,\n    vm::RunloopExit,\n};\n\n#[derive(Default)]\nstruct WriteAttr {}\nimpl BuiltinFunctionImpl for WriteAttr {\n    fn eval(\n        &self,\n        frame: &mut Frame,\n        vm: &mut crate::vm::VirtualMachine,\n    ) -> crate::vm::ExecutionResult<RunloopExit> {\n        let the_object = frame.stack.pop();\n        let the_string = VmGlobals::extract_arg(frame, |x| x.as_string().cloned())?;\n        let the_symbol = vm.globals.intern_symbol(the_string.raw_value())?;\n        let the_value = frame.stack.pop();\n        the_object\n            .write_attribute(the_symbol, the_value, &mut vm.globals)\n            .map_err(|e| e.to_vm_error_reason(the_string.raw_value()))?;\n        frame.stack.push(vm.globals.create_unit_object()?);\n        Ok(RunloopExit::Ok(()))\n    }\n\n    fn arity(&self) -> crate::arity::Arity {\n        crate::arity::Arity::required(3)\n    }\n\n    fn name(&self) -> &str {\n        \"writeattr\"\n    }\n}\n\npub(super) fn insert_builtins(builtins: &mut VmGlobals) {\n    builtins.insert_builtin::<WriteAttr>();\n}\n"
  },
  {
    "path": "vm-lib/src/console.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub trait Console: std::any::Any {\n    fn print(&mut self, s: &str) -> std::io::Result<()> {\n        print!(\"{}\", s);\n        Ok(())\n    }\n    fn println(&mut self, s: &str) -> std::io::Result<()> {\n        println!(\"{}\", s);\n        Ok(())\n    }\n    fn eprintln(&mut self, s: &str) -> std::io::Result<()> {\n        eprintln!(\"{}\", s);\n        Ok(())\n    }\n\n    fn as_any(&self) -> &dyn std::any::Any;\n}\n\n#[derive(Default, Clone, Copy)]\npub struct StdConsole;\nimpl Console for StdConsole {\n    fn as_any(&self) -> &dyn std::any::Any {\n        self\n    }\n}\n\n#[derive(Default, Clone)]\npub struct TestConsole {\n    pub stdout: String,\n    pub stderr: String,\n}\n\nimpl Console for TestConsole {\n    fn print(&mut self, s: &str) -> std::io::Result<()> {\n        self.stdout.push_str(s);\n        Ok(())\n    }\n\n    fn println(&mut self, s: &str) -> std::io::Result<()> {\n        self.stdout.push_str(s);\n        self.stdout.push('\\n');\n        Ok(())\n    }\n\n    fn eprintln(&mut self, s: &str) -> std::io::Result<()> {\n        self.stderr.push_str(s);\n        self.stderr.push('\\n');\n        Ok(())\n    }\n\n    fn as_any(&self) -> &dyn std::any::Any {\n        self\n    }\n}\n\nimpl TestConsole {\n    pub fn clear(&mut self) {\n        self.stdout.clear();\n        self.stderr.clear();\n    }\n}\n\nimpl std::io::Write for dyn Console {\n    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {\n        let s = std::str::from_utf8(buf)\n            .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, \"Invalid UTF-8\"))?;\n        self.print(s)?;\n        Ok(buf.len())\n    }\n\n    fn flush(&mut self) -> std::io::Result<()> {\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/error/backtrace.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_parser::ast::SourcePointer;\n\n#[derive(Clone, Debug, Default)]\npub struct Backtrace {\n    entries: Vec<SourcePointer>,\n}\n\nimpl Backtrace {\n    pub fn first_entry(&self) -> Option<SourcePointer> {\n        self.entries.first().cloned()\n    }\n\n    pub fn entries_iter(&self) -> std::slice::Iter<'_, SourcePointer> {\n        self.entries.iter()\n    }\n\n    pub fn push(&mut self, loc: SourcePointer) {\n        self.entries.push(loc);\n    }\n\n    pub fn len(&self) -> usize {\n        self.entries.len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.entries.is_empty()\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/error/dylib_load.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::ffi::{CString, c_char};\n\n#[repr(C)]\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum LoadStatus {\n    Success = 0,\n    Error = 1,\n}\n\n#[repr(C)]\npub struct LoadResult {\n    pub status: LoadStatus,\n    pub message: *const c_char,\n}\n\nimpl LoadResult {\n    pub fn success() -> Self {\n        Self {\n            status: LoadStatus::Success,\n            message: std::ptr::null(),\n        }\n    }\n\n    pub fn error(message: &str) -> Self {\n        Self {\n            status: LoadStatus::Error,\n            message: CString::new(message).unwrap().into_raw(),\n        }\n    }\n\n    #[allow(unused)]\n    pub(crate) fn free(self) {\n        if !self.message.is_null() {\n            unsafe {\n                let _ = CString::from_raw(self.message as *mut c_char);\n            }\n        }\n    }\n\n    pub(crate) fn into_rust_string(self) -> String {\n        assert!(!self.message.is_null());\n        let message = unsafe { CString::from_raw(self.message as *mut c_char) };\n        message.into_string().unwrap()\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/error/exception.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_parser::ast::SourcePointer;\nuse haxby_opcodes::BuiltinTypeId;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::{\n        backtrace::Backtrace,\n        vm_error::{VmError, VmErrorReason},\n    },\n    runtime_value::{RuntimeValue, list::List, object::Object},\n    symbol::{INTERNED_ATTR_ACTUAL, INTERNED_ATTR_BACKTRACE, INTERNED_ATTR_EXPECTED, Symbol},\n    vm::VirtualMachine,\n};\n\npub struct VmException {\n    pub value: RuntimeValue,\n    pub backtrace: Backtrace,\n}\n\nimpl VmException {\n    pub fn from_value(value: RuntimeValue) -> Self {\n        Self {\n            value,\n            backtrace: Default::default(),\n        }\n    }\n\n    pub fn from_value_and_loc(value: RuntimeValue, loc: Option<SourcePointer>) -> Self {\n        let mut this = VmException::from_value(value);\n        if let Some(loc) = loc {\n            this = this.thrown_at(loc);\n        }\n\n        this\n    }\n\n    pub fn thrown_at(self, loc: SourcePointer) -> Self {\n        if self.backtrace.len() == 1 && self.backtrace.first_entry().unwrap() == loc {\n            self\n        } else {\n            let mut new_bt = self.backtrace.clone();\n            new_bt.push(loc);\n            Self {\n                value: self.value.clone(),\n                backtrace: new_bt,\n            }\n        }\n    }\n\n    pub fn is_builtin_unimplemented(&self, vm: &mut VirtualMachine) -> bool {\n        self.value.is_builtin_unimplemented(vm)\n    }\n}\n\nimpl VmException {\n    pub(crate) fn fill_in_backtrace(&self, builtins: &mut VmGlobals) {\n        let bt_list = List::from(&[]);\n        for bt_entry in self.backtrace.entries_iter() {\n            let buf_name = bt_entry.buffer.name.clone();\n            let buf_line = bt_entry\n                .buffer\n                .line_index_for_position(bt_entry.location.start);\n            let buf_name = RuntimeValue::String(buf_name.into());\n            let buf_line = RuntimeValue::Integer((buf_line as i64).into());\n            bt_list.append(RuntimeValue::List(List::from(&[buf_name, buf_line])));\n        }\n        let _ = self.value.write_attribute(\n            INTERNED_ATTR_BACKTRACE,\n            RuntimeValue::List(bt_list),\n            builtins,\n        );\n    }\n}\n\nimpl VmException {\n    pub fn from_vmerror(err: VmError, builtins: &mut VmGlobals) -> Result<VmException, VmError> {\n        macro_rules! some_or_err {\n            ($opt:expr, $err:expr) => {\n                match $opt {\n                    Some(val) => val,\n                    None => return Err($err),\n                }\n            };\n        }\n\n        use crate::builtins::runtime_error::{\n            RUNTIME_ERR_CASE_DIVISION_BY_ZERO_IDX, RUNTIME_ERR_CASE_ENUM_WITHOUT_PAYLOAD_IDX,\n            RUNTIME_ERR_CASE_INDEX_OUT_OF_BOUNDS_IDX, RUNTIME_ERR_CASE_MISMATCHED_ARGC_IDX,\n            RUNTIME_ERR_CASE_NO_SUCH_CASE_IDX, RUNTIME_ERR_CASE_NO_SUCH_IDENTIFIER_IDX,\n            RUNTIME_ERR_CASE_OPERATION_FAILED_IDX, RUNTIME_ERR_CASE_UNEXPECTED_TYPE_IDX,\n        };\n\n        let rt_err_type = builtins.get_builtin_type_by_id(BuiltinTypeId::RuntimeError);\n\n        let rt_err = some_or_err!(rt_err_type.as_enum(), err);\n\n        struct ExceptionData {\n            case: usize,\n            payload: Option<RuntimeValue>,\n        }\n\n        let e_data = match &err.reason {\n            VmErrorReason::DivisionByZero => ExceptionData {\n                case: RUNTIME_ERR_CASE_DIVISION_BY_ZERO_IDX,\n                payload: None,\n            },\n            VmErrorReason::EnumWithoutPayload => ExceptionData {\n                case: RUNTIME_ERR_CASE_ENUM_WITHOUT_PAYLOAD_IDX,\n                payload: None,\n            },\n            VmErrorReason::IndexOutOfBounds(idx) => ExceptionData {\n                case: RUNTIME_ERR_CASE_INDEX_OUT_OF_BOUNDS_IDX,\n                payload: Some(RuntimeValue::Integer((*idx as i64).into())),\n            },\n            VmErrorReason::MismatchedArgumentCount(expected, actual) => {\n                let argc_mismatch_sym = builtins\n                    .intern_symbol(\"ArgcMismatch\")\n                    .expect(\"too many symbols interned\");\n                let argc_mismatch =\n                    some_or_err!(rt_err.load_named_value(builtins, argc_mismatch_sym), err);\n                let argc_mismatch = some_or_err!(argc_mismatch.as_struct(), err);\n                let argc_mismatch_obj = RuntimeValue::Object(Object::new(argc_mismatch));\n                let _ = argc_mismatch_obj.write_attribute(\n                    INTERNED_ATTR_EXPECTED,\n                    RuntimeValue::Integer((*expected as i64).into()),\n                    builtins,\n                );\n                let _ = argc_mismatch_obj.write_attribute(\n                    INTERNED_ATTR_ACTUAL,\n                    RuntimeValue::Integer((*actual as i64).into()),\n                    builtins,\n                );\n                ExceptionData {\n                    case: RUNTIME_ERR_CASE_MISMATCHED_ARGC_IDX,\n                    payload: Some(argc_mismatch_obj),\n                }\n            }\n            VmErrorReason::NoSuchCase(s) => ExceptionData {\n                case: RUNTIME_ERR_CASE_NO_SUCH_CASE_IDX,\n                payload: Some(RuntimeValue::String(s.clone().into())),\n            },\n            VmErrorReason::NoSuchIdentifier(s) => ExceptionData {\n                case: RUNTIME_ERR_CASE_NO_SUCH_IDENTIFIER_IDX,\n                payload: Some(RuntimeValue::String(s.clone().into())),\n            },\n            VmErrorReason::NoSuchSymbol(n, kind) => {\n                if let Some(name_for_sym) = builtins.resolve_symbol(Symbol(*n)) {\n                    ExceptionData {\n                        case: match kind {\n                            crate::error::vm_error::SymbolKind::Identifier => {\n                                RUNTIME_ERR_CASE_NO_SUCH_IDENTIFIER_IDX\n                            }\n                            crate::error::vm_error::SymbolKind::Case => {\n                                RUNTIME_ERR_CASE_NO_SUCH_CASE_IDX\n                            }\n                        },\n                        payload: Some(RuntimeValue::String(name_for_sym.to_owned().into())),\n                    }\n                } else {\n                    return Err(err);\n                }\n            }\n            VmErrorReason::OperationFailed(s) => ExceptionData {\n                case: RUNTIME_ERR_CASE_OPERATION_FAILED_IDX,\n                payload: Some(RuntimeValue::String(s.clone().into())),\n            },\n            VmErrorReason::UnexpectedType => ExceptionData {\n                case: RUNTIME_ERR_CASE_UNEXPECTED_TYPE_IDX,\n                payload: None,\n            },\n            _ => {\n                return Err(err);\n            }\n        };\n\n        let exception_value = RuntimeValue::EnumValue(some_or_err!(\n            rt_err.make_value(e_data.case, e_data.payload),\n            err\n        ));\n        Ok(VmException::from_value_and_loc(exception_value, err.loc))\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/error/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub mod backtrace;\npub mod dylib_load;\npub mod exception;\npub mod vm_error;\n"
  },
  {
    "path": "vm-lib/src/error/vm_error.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_compiler::bc_reader::DecodeError;\nuse aria_parser::ast::{SourcePointer, prettyprint::printout_accumulator::PrintoutAccumulator};\nuse haxby_opcodes::Opcode;\nuse thiserror::Error;\n\nuse crate::{\n    error::backtrace::Backtrace, opcodes::prettyprint::opcode_prettyprint,\n    runtime_module::RuntimeModule,\n};\n\n#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]\npub enum SymbolKind {\n    Identifier,\n    Case,\n}\n\nimpl std::fmt::Display for SymbolKind {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            SymbolKind::Identifier => write!(f, \"identifier\"),\n            SymbolKind::Case => write!(f, \"case\"),\n        }\n    }\n}\n\n#[derive(Clone, Error, PartialEq, Eq, Debug)]\npub enum VmErrorReason {\n    #[error(\"assertion failed: {0}\")]\n    AssertFailed(String),\n\n    #[error(\"'{0}' is a circular import reference\")]\n    CircularImport(String),\n\n    #[error(\"division by zero\")]\n    DivisionByZero,\n\n    #[error(\"enum value has no payload\")]\n    EnumWithoutPayload,\n\n    #[error(\"runtime stack is empty\")]\n    EmptyStack,\n\n    #[error(\"index {0} out of bounds\")]\n    IndexOutOfBounds(usize),\n\n    #[error(\"cannot import module at path '{0}': {1}\")]\n    ImportNotAvailable(String, String),\n\n    #[error(\"instruction cannot be fully decoded\")]\n    IncompleteInstruction,\n\n    #[error(\"bytecode ended without an explicit terminal instruction\")]\n    UnterminatedBytecode,\n\n    #[error(\"invalid binding\")]\n    InvalidBinding,\n\n    #[error(\"control instruction invalid\")]\n    InvalidControlInstruction,\n\n    #[error(\"mismatched argument count, expected {0} actual {1}\")]\n    MismatchedArgumentCount(usize, usize),\n\n    #[error(\"unknown named identifier: '{0}'\")]\n    NoSuchIdentifier(String),\n\n    #[error(\"'{0}' is not a valid case for this enum\")]\n    NoSuchCase(String),\n\n    #[error(\"unknown {1} symbol: '{0}'\")]\n    NoSuchSymbol(u32, SymbolKind),\n\n    #[error(\"unknown module constant value: '{0}'\")]\n    NoSuchModuleConstant(u16),\n\n    #[error(\"operation failed: {0}\")]\n    OperationFailed(String),\n\n    #[error(\"unexpected value type\")]\n    UnexpectedType,\n\n    #[error(\"VM execution is not a valid state\")]\n    UnexpectedVmState,\n\n    #[error(\"The main function must have 0, 1 or variable arguments\")]\n    InvalidMainSignature,\n\n    #[error(\"uplevel {0} not available\")]\n    UplevelOutOfBounds(usize),\n\n    #[error(\"{0} is not a known opcode\")]\n    UnknownOpcode(u8),\n\n    #[error(\"{1} is not a valid operand for opcode {0}\")]\n    InvalidVmOperand(u8, u8),\n\n    #[error(\"bytecode exceeds maximum allowed size\")]\n    BytecodeTooLarge,\n\n    #[error(\"too many symbols have been interned\")]\n    TooManyInternedSymbols,\n\n    #[error(\"VM execution halted\")]\n    VmHalted,\n}\n\nimpl From<DecodeError> for VmErrorReason {\n    fn from(value: DecodeError) -> Self {\n        match value {\n            DecodeError::DataTooLarge => VmErrorReason::BytecodeTooLarge,\n            DecodeError::EndOfStream => VmErrorReason::UnterminatedBytecode,\n            DecodeError::InsufficientData => VmErrorReason::IncompleteInstruction,\n            DecodeError::UnknownOpcode(n) => VmErrorReason::UnknownOpcode(n),\n            DecodeError::UnknownOperand(n, m) => VmErrorReason::InvalidVmOperand(n, m),\n        }\n    }\n}\n\n#[derive(Clone)]\npub struct VmError {\n    pub reason: VmErrorReason,\n    pub opcode: Option<Opcode>,\n    pub loc: Option<SourcePointer>,\n    pub backtrace: Box<Backtrace>,\n}\n\nimpl VmError {\n    pub fn prettyprint(&self, module: Option<RuntimeModule>) -> String {\n        let mut poa = PrintoutAccumulator::default();\n        poa = poa << \"vm error: \" << self.reason.to_string();\n        if let Some(opcode) = self.opcode\n            && let Some(m) = module\n        {\n            poa = {\n                let ropc = crate::opcodes::prettyprint::RuntimeOpcodePrinter {\n                    globals: None,\n                    module: Some(&m),\n                };\n                opcode_prettyprint(opcode, &ropc, poa)\n            };\n        }\n        if let Some(loc) = &self.loc {\n            poa = poa << \" at \" << loc.to_string();\n        }\n\n        poa.value()\n    }\n}\n\nimpl std::fmt::Debug for VmError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.prettyprint(None))\n    }\n}\n\nimpl From<VmErrorReason> for VmError {\n    fn from(reason: VmErrorReason) -> Self {\n        Self {\n            reason,\n            opcode: None,\n            loc: None,\n            backtrace: Default::default(),\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/frame.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_compiler::line_table::LineTable;\nuse aria_parser::ast::SourcePointer;\n\nuse crate::{\n    runtime_value::{RuntimeValue, function::Function, isa::IsaCheckable},\n    stack::Stack,\n    vm::VirtualMachine,\n};\n\npub struct LocalVariable {\n    pub val: RuntimeValue,\n    pub ty: IsaCheckable,\n}\n\nimpl Default for LocalVariable {\n    fn default() -> Self {\n        Self {\n            val: RuntimeValue::Integer(From::from(0)),\n            ty: IsaCheckable::any(),\n        }\n    }\n}\n\n#[derive(Clone)]\npub enum ControlBlock {\n    Try(u16),\n}\n\npub struct Frame {\n    pub stack: Stack<RuntimeValue>,\n    pub(crate) line_table: Option<LineTable>,\n    pub(crate) ctrl_blocks: Stack<ControlBlock>,\n    pub(crate) locals: Vec<LocalVariable>,\n    pub(crate) func: Option<Function>,\n    pub argc: u8,\n}\n\nimpl Frame {\n    pub(crate) fn drop_to_first_try(&mut self, _: &mut VirtualMachine) -> Option<u16> {\n        if let Some(block) = self.ctrl_blocks.try_pop() {\n            match block {\n                ControlBlock::Try(x) => {\n                    return Some(x);\n                }\n            }\n        }\n\n        None\n    }\n}\n\nimpl Frame {\n    pub fn new_with_function(f: Function) -> Self {\n        let mut this = Self::new_with_n_locals(f.frame_size());\n        this.set_line_table(f.line_table());\n        this.func = Some(f);\n        this\n    }\n\n    pub(crate) fn new_with_n_locals(n: u8) -> Self {\n        let mut this = Self {\n            stack: Default::default(),\n            line_table: None,\n            ctrl_blocks: Default::default(),\n            locals: Vec::with_capacity(n as usize),\n            func: None,\n            argc: 0,\n        };\n        for _ in 0..n {\n            this.locals.push(LocalVariable::default())\n        }\n        this\n    }\n\n    pub(crate) fn set_argc(&mut self, argc: u8) -> &mut Self {\n        self.argc = argc;\n        self\n    }\n\n    pub(crate) fn set_line_table(&mut self, lt: Option<&LineTable>) -> &mut Self {\n        self.line_table = lt.cloned();\n        self\n    }\n\n    pub(crate) fn get_line_table(&self) -> Option<&LineTable> {\n        self.line_table.as_ref()\n    }\n\n    pub fn get_line_entry_at_pos(&self, pos: u16) -> Option<SourcePointer> {\n        if let Some(lt) = &self.line_table {\n            lt.get(pos)\n        } else {\n            None\n        }\n    }\n\n    pub(crate) fn reset_for_function(&mut self, f: &Function) {\n        self.stack.clear();\n        self.ctrl_blocks.clear();\n        self.func = Some(f.clone());\n        self.argc = 0;\n        self.set_line_table(f.line_table());\n        let locals = f.frame_size() as usize;\n        self.locals.clear();\n        self.locals.resize_with(locals, LocalVariable::default);\n    }\n\n    pub(crate) fn reset_for_pool(mut self) -> Self {\n        self.stack.clear();\n        self.ctrl_blocks.clear();\n        self.locals.clear();\n        self.func = None;\n        self.argc = 0;\n        self.line_table = None;\n        self\n    }\n}\n\nimpl Default for Frame {\n    fn default() -> Self {\n        Self::new_with_n_locals(0)\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/lib.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_compiler::module::CompiledModule;\nuse vm::{ExecutionResult, RunloopExit, VirtualMachine, VmOptions};\n\npub mod arity;\npub mod builtins;\npub mod console;\npub mod error;\npub mod frame;\npub mod mixin_includer;\npub mod opcodes;\npub mod runtime_module;\npub mod runtime_value;\npub mod shape;\npub mod stack;\npub mod symbol;\npub mod vm;\n\n#[cfg(test)]\nmod test;\n\npub struct HaxbyEvalResult {\n    pub exit: RunloopExit,\n    pub vm: VirtualMachine,\n}\n\npub fn haxby_eval(module: CompiledModule, options: VmOptions) -> ExecutionResult<HaxbyEvalResult> {\n    let mut vm = VirtualMachine::with_options(options);\n\n    let rle = vm.load_module(\"eval\", module)?;\n    let rm = match rle {\n        RunloopExit::Ok(m) => m.module,\n        RunloopExit::Exception(e) => {\n            return Ok(HaxbyEvalResult {\n                exit: RunloopExit::Exception(e),\n                vm,\n            });\n        }\n    };\n    let rle = vm.execute_module(&rm)?;\n\n    Ok(HaxbyEvalResult { exit: rle, vm })\n}\n"
  },
  {
    "path": "vm-lib/src/mixin_includer.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::collections::HashSet;\n\nuse crate::{\n    builtins::VmGlobals,\n    runtime_value::{RuntimeValue, mixin::Mixin},\n    symbol::Symbol,\n};\n\n#[derive(Default)]\npub struct MixinIncluder {\n    mixins: Vec<Mixin>,\n}\n\nimpl MixinIncluder {\n    pub fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.mixins\n            .iter()\n            .rev()\n            .find_map(|mixin| mixin.load_named_value(builtins, name))\n    }\n\n    pub fn include(&mut self, mixin: Mixin) {\n        self.mixins.push(mixin);\n    }\n\n    pub fn contains(&self, mixin: &Mixin) -> bool {\n        for m in &self.mixins {\n            if m.isa_mixin(mixin) {\n                return true;\n            }\n        }\n        false\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> HashSet<Symbol> {\n        let mut attrs = HashSet::new();\n        for mixin in &self.mixins {\n            attrs.extend(mixin.list_attributes(builtins));\n        }\n        attrs\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/opcodes/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub mod prettyprint;\npub mod sidecar;\n"
  },
  {
    "path": "vm-lib/src/opcodes/prettyprint.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse aria_compiler::dump::StringResolver;\nuse aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator;\nuse haxby_opcodes::Opcode;\n\nuse crate::{builtins::VmGlobals, runtime_module::RuntimeModule};\n\npub(crate) struct RuntimeOpcodePrinter<'a> {\n    pub(crate) globals: Option<&'a VmGlobals>,\n    pub(crate) module: Option<&'a RuntimeModule>,\n}\n\nimpl<'a> StringResolver for RuntimeOpcodePrinter<'a> {\n    fn resolve_compile_time_constant(&self, idx: u16) -> Option<String> {\n        if let Some(module) = &self.module {\n            module\n                .get_compiled_module()\n                .resolve_compile_time_constant(idx)\n        } else {\n            None\n        }\n    }\n\n    fn resolve_run_time_symbol(&self, idx: u32) -> Option<String> {\n        if let Some(globals) = &self.globals {\n            globals\n                .resolve_symbol(crate::symbol::Symbol(idx))\n                .map(|f| f.to_string())\n        } else {\n            None\n        }\n    }\n}\n\npub(crate) fn opcode_prettyprint(\n    opcode: Opcode,\n    ropc: &RuntimeOpcodePrinter,\n    buffer: PrintoutAccumulator,\n) -> PrintoutAccumulator {\n    aria_compiler::dump::opcodes::opcode_prettyprint(opcode, ropc, buffer)\n}\n"
  },
  {
    "path": "vm-lib/src/opcodes/sidecar.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::cell::Cell;\n\nuse enum_as_inner::EnumAsInner;\n\nuse crate::shape::{ShapeId, SlotId};\n\n#[derive(Clone, Copy)]\npub struct ReadAttributeSidecar {\n    pub misses: u8,\n    pub shape_id: ShapeId,\n    pub slot_id: SlotId,\n}\n\nimpl ReadAttributeSidecar {\n    pub const MAXIMUM_ALLOWED_MISSES: u8 = 16;\n}\n\n#[derive(Clone, Copy)]\npub struct NewEnumValSidecar {\n    pub misses: u8,\n    pub shape_id: ShapeId,\n    pub slot_id: SlotId,\n}\n\n#[derive(Clone, Copy)]\npub struct EnumCheckIsCaseSidecar {\n    pub misses: u8,\n    pub shape_id: ShapeId,\n    pub slot_id: SlotId,\n}\n\nimpl NewEnumValSidecar {\n    pub const MAXIMUM_ALLOWED_MISSES: u8 = 16;\n}\n\n#[derive(Clone, Copy, EnumAsInner)]\npub enum OpcodeSidecar {\n    ReadAttribute(ReadAttributeSidecar),\n    NewEnumVal(NewEnumValSidecar),\n    EnumCheckIsCase(EnumCheckIsCaseSidecar),\n}\n\npub type SidecarCell = Cell<Option<OpcodeSidecar>>;\npub type SidecarSlice = [SidecarCell];\n\n#[cfg(debug_assertions)]\npub(crate) fn sidecar_prettyprint(\n    sidecar: OpcodeSidecar,\n    buffer: aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator,\n) -> aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator {\n    match sidecar {\n        OpcodeSidecar::ReadAttribute(sc) => {\n            buffer\n                << \"[misses=\"\n                << sc.misses\n                << \" shape_id=\"\n                << sc.shape_id.0\n                << \" slot_id=\"\n                << sc.slot_id.0\n                << \"]\"\n        }\n        OpcodeSidecar::NewEnumVal(sc) => {\n            buffer\n                << \"[misses=\"\n                << sc.misses\n                << \" shape_id=\"\n                << sc.shape_id.0\n                << \" slot_id=\"\n                << sc.slot_id.0\n                << \"]\"\n        }\n        OpcodeSidecar::EnumCheckIsCase(sc) => {\n            buffer\n                << \"[misses=\"\n                << sc.misses\n                << \" shape_id=\"\n                << sc.shape_id.0\n                << \" slot_id=\"\n                << sc.slot_id.0\n                << \"]\"\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_module.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::RefCell, collections::HashSet, rc::Rc};\n\nuse aria_compiler::module::CompiledModule;\nuse haxby_opcodes::Opcode;\nuse rustc_data_structures::fx::FxHashMap;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::vm_error::VmErrorReason,\n    runtime_value::{\n        RuntimeValue,\n        function::{BuiltinFunctionImpl, Function},\n        isa::IsaCheckable,\n    },\n    vm::VirtualMachine,\n};\n\n#[derive(Clone)]\npub struct NamedValue {\n    pub val: RuntimeValue,\n    pub ty: IsaCheckable,\n}\n\nstruct RuntimeModuleImpl {\n    compiled_module: CompiledModule,\n    indexed_constants: Vec<RuntimeValue>,\n    values: RefCell<FxHashMap<String, NamedValue>>,\n    entry_co: crate::runtime_value::runtime_code_object::CodeObject,\n}\n\nfn byte_array_to_opcode_array(bytes: &[u8]) -> aria_compiler::bc_reader::DecodeResult<Vec<Opcode>> {\n    let mut opcodes = Vec::new();\n    let mut decoder = aria_compiler::bc_reader::BytecodeReader::try_from(bytes)?;\n\n    loop {\n        let next = decoder.read_opcode();\n        match next {\n            Ok(op) => opcodes.push(op),\n            Err(err) => {\n                return match err {\n                    aria_compiler::bc_reader::DecodeError::EndOfStream => Ok(opcodes),\n                    _ => Err(err),\n                };\n            }\n        }\n    }\n}\n\nmacro_rules! replace_const_with_symbol {\n    ($vm:expr, $cm:expr, $n:expr, $opcode:expr, $target_variant:ident) => {{\n        let n_const = $cm.load_indexed_const($n).expect(\"missing constant\");\n        let n_as_str = n_const.as_string().expect(\"expected string constant\");\n        let n_as_sym = match $vm.globals.intern_symbol(&n_as_str) {\n            Ok(s) => s,\n            Err(_) => return Err(VmErrorReason::UnexpectedVmState),\n        };\n        *$opcode = Opcode::$target_variant(n_as_sym.0);\n    }};\n    ($vm:expr, $cm:expr, $arg0:expr, $n:expr, $opcode:expr, $target_variant:ident) => {{\n        let n_const = $cm.load_indexed_const($n).expect(\"missing constant\");\n        let n_as_str = n_const.as_string().expect(\"expected string constant\");\n        let n_as_sym = match $vm.globals.intern_symbol(&n_as_str) {\n            Ok(s) => s,\n            Err(_) => return Err(VmErrorReason::UnexpectedVmState),\n        };\n        *$opcode = Opcode::$target_variant($arg0, n_as_sym.0);\n    }};\n}\n\nfn replace_attribute_access_with_interned(\n    vm: &mut VirtualMachine,\n    cm: &CompiledModule,\n    opcodes: &mut Vec<Opcode>,\n) -> Result<(), VmErrorReason> {\n    for opcode in opcodes {\n        match opcode {\n            Opcode::ReadAttribute(n) => {\n                replace_const_with_symbol!(vm, cm, *n, opcode, ReadAttributeSymbol)\n            }\n            Opcode::WriteAttribute(n) => {\n                replace_const_with_symbol!(vm, cm, *n, opcode, WriteAttributeSymbol)\n            }\n            Opcode::ReadAttributeSymbol(_) | Opcode::WriteAttributeSymbol(_) => {\n                // the compiler cannot generate these instructions because it does not know\n                // what the VM will intern at runtime in what order - so if we see them in\n                // the compiled module's byte stream, it's clearly bad and we should reject\n                // loading this module\n                return Err(VmErrorReason::UnexpectedVmState);\n            }\n            Opcode::BindCase(a, n) => {\n                replace_const_with_symbol!(vm, cm, *a, *n, opcode, BindCaseSymbol)\n            }\n            Opcode::NewEnumVal(a, n) => {\n                replace_const_with_symbol!(vm, cm, *a, *n, opcode, NewEnumValSymbol)\n            }\n            Opcode::EnumCheckIsCase(n) => {\n                replace_const_with_symbol!(vm, cm, *n, opcode, EnumCheckIsCaseSymbol)\n            }\n            Opcode::BindCaseSymbol(..)\n            | Opcode::NewEnumValSymbol(..)\n            | Opcode::EnumCheckIsCaseSymbol(_) => {\n                return Err(VmErrorReason::UnexpectedVmState);\n            }\n            _ => {}\n        }\n    }\n    Ok(())\n}\n\nfn compiled_code_object_to_runtime_code_object(\n    vm: &mut VirtualMachine,\n    cm: &CompiledModule,\n    cco: aria_compiler::constant_value::CompiledCodeObject,\n) -> Result<crate::runtime_value::runtime_code_object::CodeObject, VmErrorReason> {\n    let mut ops = byte_array_to_opcode_array(cco.body.as_slice())?;\n    replace_attribute_access_with_interned(vm, cm, &mut ops)?;\n    let body: Rc<[Opcode]> = ops.into();\n\n    Ok(crate::runtime_value::runtime_code_object::CodeObject {\n        name: cco.name.clone(),\n        attribute: cco.attribute,\n        body,\n        required_argc: cco.required_argc,\n        default_argc: cco.default_argc,\n        frame_size: cco.frame_size,\n        loc: cco.loc.clone(),\n        line_table: Rc::from(cco.line_table.clone()),\n    })\n}\n\nfn compiled_constant_to_runtime_value(\n    vm: &mut VirtualMachine,\n    cm: &CompiledModule,\n    value: aria_compiler::constant_value::ConstantValue,\n) -> Result<RuntimeValue, VmErrorReason> {\n    use aria_compiler::constant_value::ConstantValue::{\n        CompiledCodeObject, Float, Integer, String,\n    };\n    match value {\n        Integer(n) => Ok(RuntimeValue::Integer(From::from(n))),\n        String(s) => Ok(RuntimeValue::String(s.into())),\n        CompiledCodeObject(cco) => Ok(RuntimeValue::CodeObject(\n            compiled_code_object_to_runtime_code_object(vm, cm, cco)?,\n        )),\n        Float(f) => Ok(RuntimeValue::Float(f.raw_value().into())),\n    }\n}\n\nimpl RuntimeModuleImpl {\n    fn new(vm: &mut VirtualMachine, cm: CompiledModule) -> Result<Self, VmErrorReason> {\n        let entry_co =\n            compiled_code_object_to_runtime_code_object(vm, &cm, cm.load_entry_code_object())?;\n\n        let mut this = Self {\n            compiled_module: cm,\n            indexed_constants: Vec::new(),\n            values: Default::default(),\n            entry_co,\n        };\n\n        let mut i = 0;\n        while i < this.compiled_module.constants.len() {\n            let c = this\n                .compiled_module\n                .load_indexed_const(i as u16)\n                .expect(\"module has missing constant data\");\n\n            let r = compiled_constant_to_runtime_value(vm, &this.compiled_module, c)?;\n            this.indexed_constants.push(r);\n\n            i += 1;\n        }\n\n        Ok(this)\n    }\n\n    fn named_values_of_this(&self) -> Vec<(String, NamedValue)> {\n        let mut ret = vec![];\n\n        for (n, v) in self.values.borrow().iter() {\n            ret.push((n.clone(), v.clone()));\n        }\n\n        ret\n    }\n\n    fn load_named_value(&self, name: &str) -> Option<RuntimeValue> {\n        self.values.borrow().get(name).map(|v| v.val.clone())\n    }\n\n    fn typedef_named_value(&self, name: &str, ty: IsaCheckable) {\n        let mut bm = self.values.borrow_mut();\n        if let Some(val) = bm.get_mut(name) {\n            val.ty = ty;\n        } else {\n            bm.insert(\n                name.to_owned(),\n                NamedValue {\n                    val: RuntimeValue::Integer(0.into()),\n                    ty,\n                },\n            );\n        }\n    }\n\n    fn store_typechecked_named_value(\n        &self,\n        name: &str,\n        val: RuntimeValue,\n        builtins: &VmGlobals,\n    ) -> Result<(), VmErrorReason> {\n        let mut bm = self.values.borrow_mut();\n        if let Some(nval) = bm.get_mut(name) {\n            if !nval.ty.isa_check(&val, builtins) {\n                Err(VmErrorReason::UnexpectedType)\n            } else {\n                nval.val = val;\n                Ok(())\n            }\n        } else {\n            Err(VmErrorReason::NoSuchIdentifier(name.to_owned()))\n        }\n    }\n\n    fn store_named_value(&self, name: &str, val: RuntimeValue) {\n        let mut bm = self.values.borrow_mut();\n        if let Some(nval) = bm.get_mut(name) {\n            nval.val = val;\n        } else {\n            bm.insert(\n                name.to_owned(),\n                NamedValue {\n                    val,\n                    ty: IsaCheckable::any(),\n                },\n            );\n        }\n    }\n\n    fn load_indexed_const(&self, idx: u16) -> Option<&RuntimeValue> {\n        self.indexed_constants.get(idx as usize)\n    }\n\n    fn list_named_values(&self) -> HashSet<String> {\n        self.values.borrow().keys().cloned().collect()\n    }\n}\n\n#[derive(Clone)]\npub struct RuntimeModule {\n    imp: Rc<RuntimeModuleImpl>,\n}\n\nimpl RuntimeModule {\n    pub fn new(vm: &mut VirtualMachine, cm: CompiledModule) -> Result<Self, VmErrorReason> {\n        Ok(Self {\n            imp: Rc::new(RuntimeModuleImpl::new(vm, cm)?),\n        })\n    }\n\n    pub fn load_entry_code_object(&self) -> &crate::runtime_value::runtime_code_object::CodeObject {\n        &self.imp.entry_co\n    }\n\n    pub(crate) fn named_values_of_this(&self) -> Vec<(String, NamedValue)> {\n        self.imp.named_values_of_this()\n    }\n\n    pub(crate) fn get_compiled_module(&self) -> &CompiledModule {\n        &self.imp.compiled_module\n    }\n\n    pub fn load_named_value(&self, name: &str) -> Option<RuntimeValue> {\n        self.imp.load_named_value(name)\n    }\n\n    pub fn typedef_named_value(&self, name: &str, ty: IsaCheckable) {\n        self.imp.typedef_named_value(name, ty)\n    }\n\n    pub fn store_named_value(&self, name: &str, val: RuntimeValue) {\n        self.imp.store_named_value(name, val)\n    }\n\n    pub fn list_named_values(&self) -> HashSet<String> {\n        self.imp.list_named_values()\n    }\n\n    pub fn store_typechecked_named_value(\n        &self,\n        name: &str,\n        val: RuntimeValue,\n        builtins: &VmGlobals,\n    ) -> Result<(), VmErrorReason> {\n        self.imp.store_typechecked_named_value(name, val, builtins)\n    }\n\n    pub fn load_indexed_const(&self, idx: u16) -> Option<&RuntimeValue> {\n        self.imp.load_indexed_const(idx)\n    }\n\n    pub fn lift_all_symbols_from_other(\n        &self,\n        prior_art: &Self,\n        vm: &crate::VirtualMachine,\n    ) -> Result<(), VmErrorReason> {\n        for (name, val) in prior_art.named_values_of_this() {\n            self.typedef_named_value(&name, val.ty.clone());\n            self.store_typechecked_named_value(&name, val.val.clone(), &vm.globals)?;\n        }\n        Ok(())\n    }\n\n    pub fn extract_value<T, U>(&self, name: &str, f: T) -> Option<U>\n    where\n        T: FnOnce(RuntimeValue) -> Option<U>,\n    {\n        f(self.load_named_value(name)?)\n    }\n\n    pub fn insert_builtin<T>(&self)\n    where\n        T: 'static + Default + BuiltinFunctionImpl,\n    {\n        let t = T::default();\n        let name = t.name().to_owned();\n        self.store_named_value(&name, RuntimeValue::Function(Function::builtin_from(t)));\n    }\n}\n\nimpl PartialEq for RuntimeModule {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for RuntimeModule {}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/boolean.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse super::builtin_value::BuiltinValue;\n\npub type BooleanValue = BuiltinValue<bool>;\n\nimpl PartialEq<BooleanValue> for BooleanValue {\n    fn eq(&self, other: &BooleanValue) -> bool {\n        self.raw_value() == other.raw_value()\n    }\n}\nimpl Eq for BooleanValue {}\n\nimpl std::ops::Not for BooleanValue {\n    type Output = BooleanValue;\n\n    fn not(self) -> Self::Output {\n        self.raw_value().not().into()\n    }\n}\n\nimpl std::ops::BitXor for &BooleanValue {\n    type Output = BooleanValue;\n\n    fn bitxor(self, rhs: Self) -> Self::Output {\n        (self.raw_value() ^ rhs.raw_value()).into()\n    }\n}\n\nimpl std::ops::BitAnd for &BooleanValue {\n    type Output = BooleanValue;\n\n    fn bitand(self, rhs: Self) -> Self::Output {\n        (*self.raw_value() && *rhs.raw_value()).into()\n    }\n}\n\nimpl std::ops::BitOr for &BooleanValue {\n    type Output = BooleanValue;\n\n    fn bitor(self, rhs: Self) -> Self::Output {\n        (*self.raw_value() || *rhs.raw_value()).into()\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/bound_function.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::rc::Rc;\n\nuse crate::{\n    frame::Frame,\n    runtime_value::function::PartialFunctionApplication,\n    vm::{ExecutionResult, VirtualMachine},\n};\n\nuse super::{CallResult, RuntimeValue, function::Function};\n\nstruct BoundFunctionImpl {\n    this: RuntimeValue,\n    func: Function,\n}\n\n#[derive(Clone)]\npub struct BoundFunction {\n    imp: Rc<BoundFunctionImpl>,\n}\n\nimpl BoundFunction {\n    pub(super) fn bind(this: RuntimeValue, func: Function) -> Self {\n        Self {\n            imp: Rc::new(BoundFunctionImpl { this, func }),\n        }\n    }\n\n    pub fn this(&self) -> &RuntimeValue {\n        &self.imp.this\n    }\n\n    pub fn func(&self) -> &Function {\n        &self.imp.func\n    }\n\n    pub fn eval(\n        &self,\n        argc: u8,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n        discard_result: bool,\n    ) -> ExecutionResult<CallResult> {\n        let partial_application =\n            PartialFunctionApplication::default().with_suffix_arg(self.this().clone());\n        self.func()\n            .eval(argc, cur_frame, vm, &partial_application, discard_result)\n    }\n}\n\nimpl PartialEq for BoundFunction {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for BoundFunction {}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/builtin_value.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::rc::Rc;\n\nuse haxby_opcodes::BuiltinTypeId;\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{builtins::VmGlobals, symbol::Symbol};\n\nuse super::object::ObjectBox;\n\npub(crate) struct BuiltinValueImpl<T>\nwhere\n    T: Clone,\n{\n    pub(crate) val: T,\n    id: BuiltinTypeId,\n    pub(crate) boxx: ObjectBox,\n}\n\nimpl<T> BuiltinValueImpl<T>\nwhere\n    T: Clone,\n{\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.boxx.list_attributes(builtins)\n    }\n}\n\n#[derive(Clone)]\npub struct BuiltinValue<T>\nwhere\n    T: Clone,\n{\n    pub(crate) imp: Rc<BuiltinValueImpl<T>>,\n}\n\ntrait GetBuiltinTypeId {\n    fn get_builtin_type_id() -> BuiltinTypeId;\n}\n\nimpl GetBuiltinTypeId for i64 {\n    #[inline]\n    fn get_builtin_type_id() -> BuiltinTypeId {\n        BuiltinTypeId::Int\n    }\n}\nimpl GetBuiltinTypeId for bool {\n    #[inline]\n    fn get_builtin_type_id() -> BuiltinTypeId {\n        BuiltinTypeId::Bool\n    }\n}\nimpl GetBuiltinTypeId for String {\n    #[inline]\n    fn get_builtin_type_id() -> BuiltinTypeId {\n        BuiltinTypeId::String\n    }\n}\nimpl GetBuiltinTypeId for f64 {\n    #[inline]\n    fn get_builtin_type_id() -> BuiltinTypeId {\n        BuiltinTypeId::Float\n    }\n}\n\nimpl<T> From<T> for BuiltinValueImpl<T>\nwhere\n    T: Clone + GetBuiltinTypeId,\n{\n    #[inline]\n    fn from(val: T) -> Self {\n        Self {\n            val,\n            id: T::get_builtin_type_id(),\n            boxx: Default::default(),\n        }\n    }\n}\n\nimpl<T> From<T> for BuiltinValue<T>\nwhere\n    T: Clone + GetBuiltinTypeId,\n{\n    #[inline]\n    fn from(val: T) -> Self {\n        Self {\n            imp: Rc::new(From::from(val)),\n        }\n    }\n}\n\nimpl<T> BuiltinValue<T>\nwhere\n    T: Clone,\n{\n    #[inline]\n    pub fn builtin_type_id(&self) -> BuiltinTypeId {\n        self.imp.id\n    }\n\n    #[inline]\n    pub fn raw_value(&self) -> &T {\n        &self.imp.val\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/enum_case.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::rc::Rc;\n\nuse crate::{builtins::VmGlobals, frame::Frame, vm::VirtualMachine};\n\nuse crate::symbol::Symbol;\n\nuse super::{RuntimeValue, enumeration::Enum};\n\npub(super) struct EnumValueImpl {\n    pub(super) enumm: Enum,\n    pub(super) case: usize,\n    pub(super) payload: Option<RuntimeValue>,\n}\n\n#[derive(Clone)]\npub struct EnumValue {\n    pub(super) imp: Rc<EnumValueImpl>,\n}\n\nimpl EnumValue {\n    pub fn get_container_enum(&self) -> &Enum {\n        &self.imp.enumm\n    }\n\n    pub fn get_case_index(&self) -> usize {\n        self.imp.case\n    }\n\n    pub fn get_payload(&self) -> Option<&RuntimeValue> {\n        self.imp.payload.as_ref()\n    }\n\n    pub fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.enumm.load_named_value(builtins, name)\n    }\n}\n\nimpl EnumValueImpl {\n    fn builtin_equals(&self, other: &Self, cur_frame: &mut Frame, vm: &mut VirtualMachine) -> bool {\n        self.enumm == other.enumm\n            && self.case == other.case\n            && match (&self.payload, &other.payload) {\n                (None, None) => true,\n                (None, Some(_)) => false,\n                (Some(_), None) => false,\n                (Some(a), Some(b)) => RuntimeValue::equals(a, b, cur_frame, vm),\n            }\n    }\n}\n\nimpl EnumValue {\n    pub(super) fn builtin_equals(\n        &self,\n        other: &Self,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp) || self.imp.builtin_equals(&other.imp, cur_frame, vm)\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/enumeration.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::{\n    cell::{Cell, RefCell},\n    rc::Rc,\n};\n\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{\n    builtins::VmGlobals,\n    runtime_value::{\n        function::{BuiltinFunctionImpl, Function},\n        isa::IsaCheckable,\n        object::ObjectBox,\n    },\n    shape::{ShapeId, SlotId},\n    symbol::Symbol,\n};\n\nuse super::{\n    RuntimeValue,\n    enum_case::{EnumValue, EnumValueImpl},\n    mixin::Mixin,\n};\n\n#[derive(Clone)]\npub struct EnumCase {\n    pub name: Symbol,\n    pub payload_type: Option<IsaCheckable>,\n}\n\npub struct EnumImpl {\n    name: String,\n    cases: RefCell<Vec<EnumCase>>,\n    case_shape: Cell<ShapeId>,\n    pub(super) entries: ObjectBox,\n    mixins: RefCell<crate::mixin_includer::MixinIncluder>,\n}\n\nimpl EnumImpl {\n    fn new(name: &str) -> Self {\n        Self {\n            name: name.to_owned(),\n            cases: Default::default(),\n            case_shape: Cell::new(crate::shape::Shapes::EMPTY_SHAPE_INDEX),\n            entries: ObjectBox::default(),\n            mixins: RefCell::new(crate::mixin_includer::MixinIncluder::default()),\n        }\n    }\n\n    pub fn add_case(&self, builtins: &mut VmGlobals, case: EnumCase) -> usize {\n        let (shape_id, slot_id) = builtins.shapes.transition(self.case_shape.get(), case.name);\n        self.case_shape.set(shape_id);\n        let slot_id = slot_id.0 as usize;\n        let mut cases = self.cases.borrow_mut();\n        if slot_id == cases.len() {\n            cases.push(case);\n        } else if slot_id < cases.len() {\n            cases[slot_id] = case;\n        } else {\n            panic!(\"enum cases should grow sequentially\");\n        }\n        slot_id\n    }\n\n    pub fn add_cases(&self, builtins: &mut VmGlobals, cases: &[EnumCase]) {\n        for case in cases {\n            self.add_case(builtins, case.clone());\n        }\n    }\n\n    fn get_case_by_idx(&self, idx: usize) -> Option<EnumCase> {\n        let b = self.cases.borrow();\n        b.get(idx).cloned()\n    }\n\n    fn get_idx_of_case_by_symbol(&self, builtins: &VmGlobals, name: Symbol) -> Option<usize> {\n        builtins\n            .shapes\n            .resolve_slot(self.case_shape.get(), name)\n            .map(|slot_id| slot_id.0 as usize)\n    }\n\n    fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        if let Some(nv) = self.entries.read(builtins, name) {\n            Some(nv.clone())\n        } else {\n            self.mixins.borrow().load_named_value(builtins, name)\n        }\n    }\n\n    fn store_named_value(&self, builtins: &mut VmGlobals, name: Symbol, val: RuntimeValue) {\n        self.entries.write(builtins, name, val);\n    }\n\n    fn include_mixin(&self, mixin: &Mixin) {\n        self.mixins.borrow_mut().include(mixin.clone());\n    }\n\n    fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.mixins.borrow().contains(mixin)\n    }\n\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        let mut attrs = self.entries.list_attributes(builtins);\n        attrs.extend(self.mixins.borrow().list_attributes(builtins));\n        attrs\n    }\n\n    fn case_shape_id(&self) -> ShapeId {\n        self.case_shape.get()\n    }\n\n    pub(super) fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(ShapeId, SlotId)> {\n        let sid = self.case_shape_id();\n        let slot_id = builtins.shapes.resolve_slot(sid, name)?;\n        Some((sid, slot_id))\n    }\n}\n\nimpl Default for EnumImpl {\n    fn default() -> Self {\n        Self::new(\"\")\n    }\n}\n\n#[derive(Clone)]\npub struct Enum {\n    pub(super) imp: Rc<EnumImpl>,\n}\n\nimpl Enum {\n    pub fn new(name: &str) -> Self {\n        Self {\n            imp: Rc::new(EnumImpl::new(name)),\n        }\n    }\n\n    pub fn new_with_cases(name: &str, cases: &[EnumCase], builtins: &mut VmGlobals) -> Self {\n        let enumm = Self::new(name);\n        enumm.imp.add_cases(builtins, cases);\n        enumm\n    }\n\n    pub fn name(&self) -> &str {\n        &self.imp.name\n    }\n\n    pub fn add_case(&self, builtins: &mut VmGlobals, case: EnumCase) -> usize {\n        self.imp.add_case(builtins, case)\n    }\n\n    pub fn get_idx_of_case_by_symbol(&self, builtins: &VmGlobals, name: Symbol) -> Option<usize> {\n        self.imp.get_idx_of_case_by_symbol(builtins, name)\n    }\n\n    pub fn get_case_by_idx(&self, idx: usize) -> Option<EnumCase> {\n        self.imp.get_case_by_idx(idx)\n    }\n\n    pub fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.load_named_value(builtins, name)\n    }\n\n    pub fn include_mixin(&self, mixin: &Mixin) {\n        self.imp.include_mixin(mixin);\n    }\n\n    pub fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.imp.isa_mixin(mixin)\n    }\n\n    pub fn make_value(&self, cidx: usize, payload: Option<RuntimeValue>) -> Option<EnumValue> {\n        match self.get_case_by_idx(cidx) {\n            Some(case) => {\n                if case.payload_type.is_some() == payload.is_some() {\n                    Some(EnumValue {\n                        imp: Rc::new(EnumValueImpl {\n                            enumm: self.clone(),\n                            case: cidx,\n                            payload,\n                        }),\n                    })\n                } else {\n                    None\n                }\n            }\n            _ => None,\n        }\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n\n    pub(crate) fn case_shape_id(&self) -> ShapeId {\n        self.imp.case_shape_id()\n    }\n\n    pub fn insert_builtin<T>(&self, builtins: &mut VmGlobals)\n    where\n        T: 'static + Default + BuiltinFunctionImpl,\n    {\n        let t = T::default();\n        let name = builtins\n            .intern_symbol(t.name())\n            .expect(\"too many symbols interned\");\n        self.imp.store_named_value(\n            builtins,\n            name,\n            RuntimeValue::Function(Function::builtin_from(t)),\n        );\n    }\n\n    pub fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(ShapeId, SlotId)> {\n        self.imp.resolve_to_slot(builtins, name)\n    }\n}\n\nimpl PartialEq for Enum {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for Enum {}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/float.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse super::{builtin_value::BuiltinValue, integer::IntegerValue};\n\npub type FloatValue = BuiltinValue<f64>;\n\nimpl PartialEq<IntegerValue> for FloatValue {\n    fn eq(&self, other: &IntegerValue) -> bool {\n        self.raw_value() == other.to_fp().raw_value()\n    }\n}\n\nimpl std::ops::Add<&FloatValue> for &FloatValue {\n    type Output = FloatValue;\n\n    fn add(self, rhs: &FloatValue) -> Self::Output {\n        From::from(self.raw_value() + rhs.raw_value())\n    }\n}\n\nimpl std::ops::Sub<&FloatValue> for &FloatValue {\n    type Output = FloatValue;\n\n    fn sub(self, rhs: &FloatValue) -> Self::Output {\n        From::from(self.raw_value() - rhs.raw_value())\n    }\n}\n\nimpl std::ops::Mul<&FloatValue> for &FloatValue {\n    type Output = FloatValue;\n\n    fn mul(self, rhs: &FloatValue) -> Self::Output {\n        From::from(self.raw_value() * rhs.raw_value())\n    }\n}\n\nimpl std::ops::Div<&FloatValue> for &FloatValue {\n    type Output = FloatValue;\n\n    fn div(self, rhs: &FloatValue) -> Self::Output {\n        From::from(self.raw_value() / rhs.raw_value())\n    }\n}\n\nimpl std::ops::Rem<&FloatValue> for &FloatValue {\n    type Output = FloatValue;\n\n    fn rem(self, rhs: &FloatValue) -> Self::Output {\n        From::from(self.raw_value() % rhs.raw_value())\n    }\n}\n\nimpl std::ops::Neg for &FloatValue {\n    type Output = FloatValue;\n\n    fn neg(self) -> Self::Output {\n        From::from(-self.raw_value())\n    }\n}\n\nimpl PartialEq<FloatValue> for FloatValue {\n    fn eq(&self, other: &FloatValue) -> bool {\n        self.raw_value() == other.raw_value()\n    }\n}\nimpl Eq for FloatValue {}\n\nimpl PartialOrd<FloatValue> for FloatValue {\n    fn partial_cmp(&self, other: &FloatValue) -> Option<std::cmp::Ordering> {\n        Some(self.cmp(other))\n    }\n}\nimpl Ord for FloatValue {\n    fn cmp(&self, other: &Self) -> std::cmp::Ordering {\n        self.raw_value()\n            .partial_cmp(other.raw_value())\n            .unwrap_or(std::cmp::Ordering::Equal)\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/function.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{collections::HashMap, rc::Rc};\n\nuse aria_compiler::line_table::LineTable;\nuse aria_parser::ast::SourcePointer;\nuse haxby_opcodes::{\n    Opcode,\n    function_attribs::{FUNC_ACCEPTS_VARARG, FUNC_IS_METHOD, METHOD_ATTRIBUTE_TYPE},\n};\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{\n    arity::Arity,\n    builtins::VmGlobals,\n    frame::Frame,\n    runtime_module::RuntimeModule,\n    symbol::Symbol,\n    vm::{ExecutionResult, RunloopExit, VirtualMachine},\n};\n\nuse super::{\n    CallResult, RuntimeValue, list::List, object::ObjectBox, runtime_code_object::CodeObject,\n};\n\npub trait BuiltinFunctionImpl {\n    fn eval(&self, frame: &mut Frame, vm: &mut VirtualMachine) -> ExecutionResult<RunloopExit>;\n    fn arity(&self) -> Arity;\n    fn attrib_byte(&self) -> u8 {\n        0\n    }\n    fn name(&self) -> &str;\n}\n\npub struct BuiltinFunction {\n    pub body: Rc<dyn BuiltinFunctionImpl>,\n    pub(crate) boxx: ObjectBox,\n}\n\nimpl BuiltinFunction {\n    pub fn new(body: Rc<dyn BuiltinFunctionImpl>) -> Self {\n        Self {\n            body,\n            boxx: Default::default(),\n        }\n    }\n}\n\npub struct BytecodeFunction {\n    pub name: String,\n    pub body: Rc<[Opcode]>,\n    pub sidecar: Rc<[std::cell::Cell<Option<crate::opcodes::sidecar::OpcodeSidecar>>]>,\n    pub arity: Arity,\n    pub frame_size: u8,\n    pub line_table: Rc<LineTable>,\n    pub loc: SourcePointer,\n    pub attrib_byte: u8,\n    pub module: RuntimeModule,\n    pub(crate) boxx: ObjectBox,\n    uplevels: std::cell::RefCell<HashMap<u8, RuntimeValue>>,\n}\n\nimpl BytecodeFunction {\n    pub(crate) fn store_uplevel(&self, idx: u8, val: RuntimeValue) {\n        self.uplevels.borrow_mut().insert(idx, val);\n    }\n\n    pub(crate) fn read_uplevel(&self, idx: u8) -> Option<RuntimeValue> {\n        self.uplevels.borrow().get(&idx).cloned()\n    }\n}\n\n#[derive(enum_as_inner::EnumAsInner)]\npub(crate) enum FunctionImpl {\n    BytecodeFunction(BytecodeFunction),\n    BuiltinFunction(BuiltinFunction),\n}\n\n#[derive(Clone)]\npub struct Function {\n    pub(crate) imp: Rc<FunctionImpl>,\n}\n\nimpl FunctionImpl {\n    pub(crate) fn attribute(&self) -> FunctionAttribute {\n        match self {\n            Self::BytecodeFunction(bc) => FunctionAttribute::from(bc.attrib_byte),\n            Self::BuiltinFunction(bf) => FunctionAttribute::from(bf.body.attrib_byte()),\n        }\n    }\n\n    pub(crate) fn line_table(&self) -> Option<&LineTable> {\n        match self {\n            Self::BytecodeFunction(bc) => Some(&bc.line_table),\n            Self::BuiltinFunction(_) => None,\n        }\n    }\n\n    pub(crate) fn arity(&self) -> Arity {\n        match self {\n            Self::BytecodeFunction(bc) => bc.arity,\n            Self::BuiltinFunction(bf) => bf.body.arity(),\n        }\n    }\n\n    pub(crate) fn frame_size(&self) -> u8 {\n        match self {\n            Self::BytecodeFunction(bc) => bc.frame_size,\n            Self::BuiltinFunction(_) => 0,\n        }\n    }\n\n    pub(crate) fn name(&self) -> &str {\n        match self {\n            Self::BytecodeFunction(bc) => &bc.name,\n            Self::BuiltinFunction(bf) => bf.body.name(),\n        }\n    }\n\n    pub(crate) fn loc(&self) -> Option<&SourcePointer> {\n        match self {\n            Self::BytecodeFunction(bc) => Some(&bc.loc),\n            Self::BuiltinFunction(_) => None,\n        }\n    }\n\n    fn get_attribute_store(&self) -> &ObjectBox {\n        match self {\n            Self::BytecodeFunction(bc) => &bc.boxx,\n            Self::BuiltinFunction(bf) => &bf.boxx,\n        }\n    }\n}\n\nimpl Function {\n    pub fn attribute(&self) -> FunctionAttribute {\n        self.imp.attribute()\n    }\n\n    pub fn line_table(&self) -> Option<&LineTable> {\n        self.imp.line_table()\n    }\n\n    pub fn arity(&self) -> Arity {\n        self.imp.arity()\n    }\n\n    pub fn frame_size(&self) -> u8 {\n        self.imp.frame_size()\n    }\n\n    pub fn varargs(&self) -> bool {\n        self.attribute().is_vararg()\n    }\n\n    pub fn name(&self) -> &str {\n        self.imp.name()\n    }\n\n    pub fn loc(&self) -> Option<&SourcePointer> {\n        self.imp.loc()\n    }\n\n    pub(super) fn get_attribute_store(&self) -> &ObjectBox {\n        self.imp.get_attribute_store()\n    }\n}\n\npub struct FunctionAttribute {\n    val: u8,\n}\n\nimpl From<u8> for FunctionAttribute {\n    fn from(val: u8) -> Self {\n        Self { val }\n    }\n}\n\nimpl FunctionAttribute {\n    pub fn is_free(&self) -> bool {\n        self.val & FUNC_IS_METHOD == 0\n    }\n\n    pub fn is_vararg(&self) -> bool {\n        self.val & FUNC_ACCEPTS_VARARG != 0\n    }\n\n    pub fn is_method(&self) -> bool {\n        self.val & FUNC_IS_METHOD == FUNC_IS_METHOD\n    }\n\n    pub fn is_instance_method(&self) -> bool {\n        self.is_method() && (self.val & METHOD_ATTRIBUTE_TYPE == 0)\n    }\n\n    pub fn is_type_method(&self) -> bool {\n        self.is_method() && (self.val & METHOD_ATTRIBUTE_TYPE == METHOD_ATTRIBUTE_TYPE)\n    }\n}\n\nimpl FunctionImpl {\n    pub fn new_builtin<T>() -> Self\n    where\n        T: 'static + BuiltinFunctionImpl + Default,\n    {\n        Self::BuiltinFunction(BuiltinFunction::new(Rc::new(T::default())))\n    }\n\n    pub fn builtin_from<T>(val: T) -> Self\n    where\n        T: 'static + BuiltinFunctionImpl + Default,\n    {\n        Self::BuiltinFunction(BuiltinFunction::new(Rc::new(val)))\n    }\n\n    pub fn from_code_object(co: &CodeObject, m: &RuntimeModule) -> Self {\n        let rc = co.body.clone();\n        let sidecar = (0..rc.len())\n            .map(|_| std::cell::Cell::new(None))\n            .collect::<Vec<_>>();\n        let lt = co.line_table.clone();\n        let bcf = BytecodeFunction {\n            name: co.name.clone(),\n            body: rc,\n            sidecar: sidecar.into(),\n            arity: Arity {\n                required: co.required_argc,\n                optional: co.default_argc,\n            },\n            frame_size: co.frame_size,\n            line_table: lt,\n            loc: co.loc.clone(),\n            attrib_byte: co.attribute,\n            module: m.clone(),\n            boxx: Default::default(),\n            uplevels: Default::default(),\n        };\n        Self::BytecodeFunction(bcf)\n    }\n\n    fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        match self {\n            FunctionImpl::BytecodeFunction(b) => &b.boxx,\n            FunctionImpl::BuiltinFunction(b) => &b.boxx,\n        }\n        .read(builtins, name)\n    }\n\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        match self {\n            FunctionImpl::BytecodeFunction(b) => b.boxx.list_attributes(builtins),\n            FunctionImpl::BuiltinFunction(b) => b.boxx.list_attributes(builtins),\n        }\n    }\n}\n\n#[derive(Default)]\npub struct PartialFunctionApplication {\n    suffix_args: Vec<RuntimeValue>,\n}\n\nimpl PartialFunctionApplication {\n    pub fn with_suffix_arg(mut self, arg: RuntimeValue) -> Self {\n        self.suffix_args.push(arg);\n        self\n    }\n}\n\nimpl Function {\n    pub fn new_builtin<T>() -> Self\n    where\n        T: 'static + BuiltinFunctionImpl + Default,\n    {\n        Self {\n            imp: Rc::new(FunctionImpl::new_builtin::<T>()),\n        }\n    }\n\n    pub fn builtin_from<T>(val: T) -> Self\n    where\n        T: 'static + BuiltinFunctionImpl + Default,\n    {\n        Self {\n            imp: Rc::new(FunctionImpl::builtin_from(val)),\n        }\n    }\n\n    pub fn from_code_object(co: &CodeObject, m: &RuntimeModule) -> Self {\n        Self {\n            imp: Rc::new(FunctionImpl::from_code_object(co, m)),\n        }\n    }\n\n    pub fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.read(builtins, name)\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n\n    // DO NOT CALL unless you are Function or BoundFunction\n    pub(super) fn eval_in_frame(\n        &self,\n        argc: u8,\n        target_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> ExecutionResult<RunloopExit> {\n        match self.imp.as_ref() {\n            FunctionImpl::BytecodeFunction(bcf) => {\n                target_frame.set_argc(argc);\n                vm.eval_bytecode_in_frame(&bcf.module, &bcf.body, &bcf.sidecar, target_frame)\n            }\n            FunctionImpl::BuiltinFunction(bnf) => bnf.body.eval(target_frame, vm),\n        }\n    }\n\n    pub fn eval(\n        &self,\n        argc: u8,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n        other_args: &PartialFunctionApplication,\n        discard_result: bool,\n    ) -> ExecutionResult<CallResult> {\n        let other_argc = other_args.suffix_args.len() as u8;\n        let effective_argc = argc + other_argc;\n        let fixed_arity = self.arity().required + self.arity().optional;\n\n        if self.attribute().is_vararg() {\n            if effective_argc < self.arity().required {\n                return Err(\n                    crate::error::vm_error::VmErrorReason::MismatchedArgumentCount(\n                        self.arity().required as usize,\n                        effective_argc as usize,\n                    )\n                    .into(),\n                );\n            }\n        } else {\n            if effective_argc < self.arity().required {\n                return Err(\n                    crate::error::vm_error::VmErrorReason::MismatchedArgumentCount(\n                        self.arity().required as usize,\n                        effective_argc as usize,\n                    )\n                    .into(),\n                );\n            }\n            if effective_argc > fixed_arity {\n                return Err(\n                    crate::error::vm_error::VmErrorReason::MismatchedArgumentCount(\n                        fixed_arity as usize,\n                        effective_argc as usize,\n                    )\n                    .into(),\n                );\n            }\n        }\n\n        let mut new_frame = vm.acquire_frame(self);\n\n        if self.attribute().is_vararg() {\n            let mut popped_args = cur_frame.stack.pop_count(argc as usize);\n            let split_at = (fixed_arity - other_argc) as usize;\n            let varargs = popped_args.split_off(split_at.min(popped_args.len()));\n\n            let l = List::default();\n            for arg in varargs {\n                l.append(arg);\n            }\n\n            new_frame.stack.push(super::RuntimeValue::List(l));\n            for arg in popped_args.into_iter().rev() {\n                new_frame.stack.push(arg);\n            }\n        } else {\n            for item in cur_frame.stack.pop_count(argc as usize).into_iter().rev() {\n                new_frame.stack.push(item);\n            }\n        }\n\n        for arg in &other_args.suffix_args {\n            new_frame.stack.push(arg.clone());\n        }\n\n        let eval_result = self.eval_in_frame(effective_argc, &mut new_frame, vm);\n        let result = match eval_result {\n            Ok(RunloopExit::Ok(_)) => match new_frame.stack.try_pop() {\n                Some(ret) => {\n                    if !discard_result {\n                        cur_frame.stack.push(ret.clone());\n                    }\n                    Ok(CallResult::Ok(ret))\n                }\n                _ => panic!(\"functions must return a value\"),\n            },\n            Ok(RunloopExit::Exception(e)) => Ok(CallResult::Exception(e)),\n            Err(err) => Err(err),\n        };\n\n        vm.release_frame(new_frame);\n        result\n    }\n}\n\nimpl PartialEq for FunctionImpl {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (Self::BytecodeFunction(l0), Self::BytecodeFunction(r0)) => {\n                Rc::ptr_eq(&l0.body, &r0.body)\n            }\n            (Self::BuiltinFunction(l0), Self::BuiltinFunction(r0)) => {\n                Rc::ptr_eq(&l0.body, &r0.body)\n            }\n            _ => false,\n        }\n    }\n}\nimpl Eq for FunctionImpl {}\n\nimpl PartialEq for Function {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp) || self.imp.eq(&other.imp)\n    }\n}\nimpl Eq for Function {}\n\nimpl std::fmt::Debug for Function {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let name = self.name();\n        if let Some(loc) = self.loc() {\n            write!(f, \"<function {name} at {loc}>\")\n        } else {\n            write!(f, \"<function {name}>\")\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/integer.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse super::{builtin_value::BuiltinValue, float::FloatValue};\n\npub type IntegerValue = BuiltinValue<i64>;\n\nimpl IntegerValue {\n    pub fn to_fp(&self) -> FloatValue {\n        (*self.raw_value() as f64).into()\n    }\n}\n\nimpl PartialEq<FloatValue> for IntegerValue {\n    fn eq(&self, other: &FloatValue) -> bool {\n        self.to_fp() == *other\n    }\n}\n\nimpl std::ops::Add<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn add(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value().wrapping_add(*rhs.raw_value()))\n    }\n}\n\nimpl std::ops::Sub<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn sub(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value().wrapping_sub(*rhs.raw_value()))\n    }\n}\n\nimpl std::ops::Mul<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn mul(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value().wrapping_mul(*rhs.raw_value()))\n    }\n}\n\nimpl std::ops::Div<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn div(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value().wrapping_div(*rhs.raw_value()))\n    }\n}\n\nimpl std::ops::Rem<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn rem(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value().wrapping_rem(*rhs.raw_value()))\n    }\n}\n\nimpl std::ops::Neg for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn neg(self) -> Self::Output {\n        From::from(-self.raw_value())\n    }\n}\n\nimpl std::ops::BitAnd<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn bitand(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value() & rhs.raw_value())\n    }\n}\n\nimpl std::ops::BitOr<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn bitor(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value() | rhs.raw_value())\n    }\n}\n\nimpl std::ops::BitXor<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn bitxor(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value() ^ rhs.raw_value())\n    }\n}\n\nimpl std::ops::Shl<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn shl(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value() << rhs.raw_value())\n    }\n}\n\nimpl std::ops::Shr<&IntegerValue> for &IntegerValue {\n    type Output = IntegerValue;\n\n    #[inline]\n    fn shr(self, rhs: &IntegerValue) -> Self::Output {\n        From::from(self.raw_value() >> rhs.raw_value())\n    }\n}\n\nimpl PartialEq<IntegerValue> for IntegerValue {\n    #[inline]\n    fn eq(&self, other: &IntegerValue) -> bool {\n        self.raw_value() == other.raw_value()\n    }\n}\nimpl Eq for IntegerValue {}\n\nimpl PartialOrd<IntegerValue> for IntegerValue {\n    #[inline]\n    fn partial_cmp(&self, other: &IntegerValue) -> Option<std::cmp::Ordering> {\n        Some(self.cmp(other))\n    }\n}\nimpl Ord for IntegerValue {\n    #[inline]\n    fn cmp(&self, other: &Self) -> std::cmp::Ordering {\n        self.raw_value().cmp(other.raw_value())\n    }\n}\n\nimpl PartialEq<i64> for IntegerValue {\n    #[inline]\n    fn eq(&self, other: &i64) -> bool {\n        *self.raw_value() == *other\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/isa.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse crate::builtins::VmGlobals;\nuse crate::runtime_value::mixin::Mixin;\nuse crate::runtime_value::{RuntimeValue, RuntimeValueType};\n\n#[derive(Clone, PartialEq, Eq)]\npub enum IsaCheckable {\n    Type(RuntimeValueType),\n    Mixin(Mixin),\n    Union(Vec<IsaCheckable>),\n    Intersection(Vec<IsaCheckable>),\n}\n\nimpl std::fmt::Debug for IsaCheckable {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            IsaCheckable::Type(t) => write!(f, \"({:?})\", t),\n            IsaCheckable::Mixin(m) => write!(f, \"<mixin{}>\", m.name()),\n            IsaCheckable::Union(us) => {\n                write!(f, \"(\")?;\n                for (i, u) in us.iter().enumerate() {\n                    if i > 0 {\n                        write!(f, \" | \")?;\n                    }\n                    write!(f, \"{:?}\", u)?;\n                }\n                write!(f, \")\")\n            }\n            IsaCheckable::Intersection(is) => {\n                write!(f, \"(\")?;\n                for (i, u) in is.iter().enumerate() {\n                    if i > 0 {\n                        write!(f, \" & \")?;\n                    }\n                    write!(f, \"{:?}\", u)?;\n                }\n                write!(f, \")\")\n            }\n        }\n    }\n}\n\nimpl IsaCheckable {\n    fn isa(val: &RuntimeValue, t: &RuntimeValueType, builtins: &VmGlobals) -> bool {\n        match t {\n            RuntimeValueType::Any => true,\n            RuntimeValueType::Union(u) => {\n                for u_k in u {\n                    if Self::isa(val, u_k, builtins) {\n                        return true;\n                    }\n                }\n                false\n            }\n            _ => RuntimeValueType::get_type(val, builtins) == *t,\n        }\n    }\n\n    fn isa_mixin(val: &RuntimeValue, mixin: &Mixin, builtins: &VmGlobals) -> bool {\n        if let Some(obj) = val.as_object() {\n            obj.get_struct().isa_mixin(mixin)\n        } else if let Some(env) = val.as_enum_value() {\n            env.get_container_enum().isa_mixin(mixin)\n        } else if let Some(m) = val.as_mixin() {\n            m.isa_mixin(mixin)\n        } else if let Some(st) = val.as_struct() {\n            st.isa_mixin(mixin)\n        } else if let Some(en) = val.as_enum() {\n            en.isa_mixin(mixin)\n        } else if let Some(btt) = RuntimeValueType::get_type(val, builtins).as_rust_native() {\n            btt.isa_mixin(mixin)\n        } else {\n            false\n        }\n    }\n}\n\nimpl IsaCheckable {\n    pub fn isa_check(&self, other: &RuntimeValue, builtins: &VmGlobals) -> bool {\n        match self {\n            IsaCheckable::Type(t) => IsaCheckable::isa(other, t, builtins),\n            IsaCheckable::Mixin(m) => IsaCheckable::isa_mixin(other, m, builtins),\n            IsaCheckable::Union(us) => us.iter().any(|u| u.isa_check(other, builtins)),\n            IsaCheckable::Intersection(is) => is.iter().all(|i| i.isa_check(other, builtins)),\n        }\n    }\n\n    pub fn any() -> Self {\n        IsaCheckable::Type(RuntimeValueType::Any)\n    }\n}\n\nimpl TryFrom<&RuntimeValue> for IsaCheckable {\n    type Error = ();\n\n    fn try_from(value: &RuntimeValue) -> Result<Self, Self::Error> {\n        if let Some(mixin) = value.as_mixin() {\n            Ok(IsaCheckable::Mixin(mixin.clone()))\n        } else if let Some(t) = value.as_type() {\n            Ok(IsaCheckable::Type(t.clone()))\n        } else if let Some(c) = value.as_type_check() {\n            Ok(c.clone())\n        } else {\n            Err(())\n        }\n    }\n}\n\nimpl std::ops::BitOr<&IsaCheckable> for IsaCheckable {\n    type Output = IsaCheckable;\n\n    fn bitor(self, rhs: &IsaCheckable) -> Self::Output {\n        match (self, rhs) {\n            (IsaCheckable::Union(xs), IsaCheckable::Union(ys)) => {\n                let mut combined = xs;\n                for y in ys {\n                    if !combined.contains(y) {\n                        combined.push(y.clone());\n                    }\n                }\n                IsaCheckable::Union(combined)\n            }\n\n            (IsaCheckable::Union(xs), y) => {\n                let mut combined = xs;\n                if !combined.contains(y) {\n                    combined.push(y.clone());\n                }\n                IsaCheckable::Union(combined)\n            }\n\n            (x, IsaCheckable::Union(ys)) => {\n                let mut combined = ys.clone();\n                if !combined.contains(&x) {\n                    combined.push(x);\n                }\n                IsaCheckable::Union(combined)\n            }\n\n            (x, y) => {\n                if x == *y {\n                    x\n                } else {\n                    IsaCheckable::Union(vec![x, y.clone()])\n                }\n            }\n        }\n    }\n}\n\nimpl std::ops::BitAnd<&IsaCheckable> for IsaCheckable {\n    type Output = IsaCheckable;\n\n    fn bitand(self, rhs: &IsaCheckable) -> Self::Output {\n        match (self, rhs) {\n            (IsaCheckable::Intersection(xs), IsaCheckable::Intersection(ys)) => {\n                let mut combined = xs;\n                for y in ys {\n                    if !combined.contains(y) {\n                        combined.push(y.clone());\n                    }\n                }\n                IsaCheckable::Intersection(combined)\n            }\n\n            (IsaCheckable::Intersection(xs), y) => {\n                let mut combined = xs;\n                if !combined.contains(y) {\n                    combined.push(y.clone());\n                }\n                IsaCheckable::Intersection(combined)\n            }\n\n            (x, IsaCheckable::Intersection(ys)) => {\n                let mut combined = ys.clone();\n                if !combined.contains(&x) {\n                    combined.push(x);\n                }\n                IsaCheckable::Intersection(combined)\n            }\n\n            (x, y) => {\n                if x == *y {\n                    x\n                } else {\n                    IsaCheckable::Intersection(vec![x, y.clone()])\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/kind.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse enum_as_inner::EnumAsInner;\nuse haxby_opcodes::BuiltinTypeId;\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{arity::Arity, builtins::VmGlobals, symbol::Symbol};\n\nuse super::{\n    AttributeError, RuntimeValue, enumeration::Enum, rust_native_type::RustNativeType,\n    structure::Struct,\n};\n\n#[derive(Clone, PartialEq, Eq)]\npub struct FunctionType {\n    pub arity: Arity,\n    pub varargs: bool,\n}\n\nimpl std::fmt::Debug for FunctionType {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"({}, {}{})\",\n            self.arity.required,\n            self.arity.optional,\n            if self.varargs { \", ...\" } else { \"\" }\n        )\n    }\n}\n\n#[derive(EnumAsInner, Clone)]\npub enum RuntimeValueType {\n    Any,\n    RustNative(RustNativeType),\n    CodeObject,\n    Module,\n    Function(FunctionType),\n    BoundFunction(FunctionType),\n    Mixin,\n    Opaque,\n    TypeCheck,\n    Struct(Struct),\n    Enum(Enum),\n    Union(Vec<RuntimeValueType>),\n}\n\nimpl PartialEq for RuntimeValueType {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (Self::Function(f0), Self::Function(f1)) => f0 == f1,\n            (Self::BoundFunction(f0), Self::BoundFunction(f1)) => f0 == f1,\n            (Self::RustNative(l0), Self::RustNative(r0)) => l0 == r0,\n            (Self::Struct(l0), Self::Struct(r0)) => l0 == r0,\n            (Self::Enum(l0), Self::Enum(r0)) => l0 == r0,\n            (Self::Union(l0), Self::Union(r0)) => {\n                if l0.len() != r0.len() {\n                    false\n                } else {\n                    for vk_a in l0 {\n                        if !r0.contains(vk_a) {\n                            return false;\n                        }\n                    }\n                    true\n                }\n            }\n            _ => core::mem::discriminant(self) == core::mem::discriminant(other),\n        }\n    }\n}\nimpl Eq for RuntimeValueType {}\n\nimpl RuntimeValueType {\n    pub fn get_type(value: &RuntimeValue, builtins: &VmGlobals) -> Self {\n        match value {\n            RuntimeValue::Object(obj) => Self::Struct(obj.get_struct().clone()),\n            RuntimeValue::EnumValue(env) => Self::Enum(env.get_container_enum().clone()),\n            RuntimeValue::CodeObject(_) => Self::CodeObject,\n            RuntimeValue::Module(_) => Self::Module,\n            RuntimeValue::Mixin(_) => Self::Mixin,\n            RuntimeValue::Opaque(_) => Self::Opaque,\n            RuntimeValue::TypeCheck(_) => Self::TypeCheck,\n            RuntimeValue::Function(f) => Self::Function(FunctionType {\n                arity: f.arity(),\n                varargs: f.varargs(),\n            }),\n            RuntimeValue::BoundFunction(bf) => Self::Function(FunctionType {\n                arity: bf.func().arity(),\n                varargs: bf.func().varargs(),\n            }),\n            RuntimeValue::Type(_) => builtins.get_builtin_type_by_id(BuiltinTypeId::Type),\n            RuntimeValue::Boolean(_) => builtins.get_builtin_type_by_id(BuiltinTypeId::Bool),\n            RuntimeValue::Integer(_) => builtins.get_builtin_type_by_id(BuiltinTypeId::Int),\n            RuntimeValue::Float(_) => builtins.get_builtin_type_by_id(BuiltinTypeId::Float),\n            RuntimeValue::List(_) => builtins.get_builtin_type_by_id(BuiltinTypeId::List),\n            RuntimeValue::String(_) => builtins.get_builtin_type_by_id(BuiltinTypeId::String),\n        }\n    }\n}\n\nimpl std::fmt::Debug for RuntimeValueType {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Any => write!(f, \"Any\"),\n            Self::RustNative(b) => write!(f, \"{b:?}\"),\n            Self::CodeObject => write!(f, \"CodeObject\"),\n            Self::Module => write!(f, \"Module\"),\n            Self::Mixin => write!(f, \"Mixin\"),\n            Self::Opaque => write!(f, \"Opaque\"),\n            Self::TypeCheck => write!(f, \"TypeCheck\"),\n            Self::Function(ft) => write!(f, \"Function{ft:?}\"),\n            Self::BoundFunction(ft) => write!(f, \"BoundFunction{ft:?}\"),\n            Self::Struct(s) => write!(f, \"Struct {}\", s.name()),\n            Self::Enum(e) => write!(f, \"Enum {}\", e.name()),\n            Self::Union(v) => {\n                let us = v\n                    .iter()\n                    .map(|x| format!(\"{x:?}\"))\n                    .collect::<Vec<_>>()\n                    .join(\"|\");\n                write!(f, \"{us}\")\n            }\n        }\n    }\n}\n\nimpl std::ops::BitOr<&RuntimeValueType> for &RuntimeValueType {\n    type Output = RuntimeValueType;\n\n    fn bitor(self, rhs: &RuntimeValueType) -> Self::Output {\n        if *self == *rhs {\n            return self.clone();\n        }\n\n        match (self, rhs) {\n            (RuntimeValueType::Any, _) | (_, RuntimeValueType::Any) => RuntimeValueType::Any,\n            (RuntimeValueType::Union(a), RuntimeValueType::Union(b)) => {\n                let mut uret = a.clone();\n                for b_vk in b {\n                    if !uret.contains(b_vk) {\n                        uret.push(b_vk.clone())\n                    }\n                }\n                RuntimeValueType::Union(uret)\n            }\n            (RuntimeValueType::Union(a), _) => {\n                if a.contains(rhs) {\n                    self.clone()\n                } else {\n                    let mut uret = a.clone();\n                    uret.push(rhs.clone());\n                    RuntimeValueType::Union(uret)\n                }\n            }\n            (_, RuntimeValueType::Union(b)) => {\n                if b.contains(self) {\n                    rhs.clone()\n                } else {\n                    let mut uret = b.clone();\n                    uret.push(self.clone());\n                    RuntimeValueType::Union(uret)\n                }\n            }\n            _ => RuntimeValueType::Union(vec![self.clone(), rhs.clone()]),\n        }\n    }\n}\n\nimpl RuntimeValueType {\n    pub fn read_attribute(\n        &self,\n        builtins: &VmGlobals,\n        attr_name: Symbol,\n    ) -> Result<RuntimeValue, AttributeError> {\n        if let Some(struk) = self.as_struct() {\n            match struk.load_named_value(builtins, attr_name) {\n                Some(x) => Ok(x),\n                None => Err(AttributeError::NoSuchAttribute),\n            }\n        } else if let Some(enumm) = self.as_enum() {\n            match enumm.load_named_value(builtins, attr_name) {\n                Some(x) => Ok(x),\n                None => Err(AttributeError::NoSuchAttribute),\n            }\n        } else if let Some(bt) = self.as_rust_native() {\n            match bt.read(builtins, attr_name) {\n                Some(x) => Ok(x),\n                None => Err(AttributeError::NoSuchAttribute),\n            }\n        } else {\n            Err(AttributeError::ValueHasNoAttributes)\n        }\n    }\n\n    pub(super) fn get_attribute_store(&self) -> Option<&super::object::ObjectBox> {\n        match self {\n            RuntimeValueType::RustNative(rt) => Some(rt.get_boxx().as_ref()),\n            RuntimeValueType::Struct(st) => Some(&st.imp.as_ref().entries),\n            RuntimeValueType::Enum(en) => Some(&en.imp.as_ref().entries),\n            RuntimeValueType::Union(_) => None,\n            RuntimeValueType::Function(_) => None,\n            RuntimeValueType::BoundFunction(_) => None,\n            RuntimeValueType::CodeObject => None,\n            RuntimeValueType::Module => None,\n            RuntimeValueType::Mixin => None,\n            RuntimeValueType::Opaque => None,\n            RuntimeValueType::TypeCheck => None,\n            RuntimeValueType::Any => None,\n        }\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        if let Some(struk) = self.as_struct() {\n            struk.list_attributes(builtins)\n        } else if let Some(enumm) = self.as_enum() {\n            enumm.list_attributes(builtins)\n        } else if let Some(bt) = self.as_rust_native() {\n            bt.list_attributes(builtins)\n        } else {\n            Default::default()\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/list.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::UnsafeCell, rc::Rc};\n\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::vm_error::{VmError, VmErrorReason},\n    frame::Frame,\n    runtime_value::object::ObjectBox,\n    symbol::Symbol,\n    vm::{ExecutionResult, VirtualMachine},\n};\n\nuse super::RuntimeValue;\n\n#[derive(Default)]\npub(super) struct ListImpl {\n    values: UnsafeCell<Vec<RuntimeValue>>,\n    pub(super) boxx: ObjectBox,\n}\n\nimpl ListImpl {\n    #[allow(clippy::mut_from_ref)]\n    #[inline]\n    fn get(&self) -> &Vec<RuntimeValue> {\n        unsafe { &*self.values.get() }\n    }\n\n    #[allow(clippy::mut_from_ref)]\n    #[inline]\n    fn get_mut(&self) -> &mut Vec<RuntimeValue> {\n        unsafe { &mut *self.values.get() }\n    }\n\n    fn new_with_capacity(cap: usize) -> Self {\n        Self {\n            values: UnsafeCell::new(Vec::with_capacity(cap)),\n            boxx: ObjectBox::default(),\n        }\n    }\n\n    fn len(&self) -> usize {\n        self.get().len()\n    }\n\n    fn is_empty(&self) -> bool {\n        self.get().is_empty()\n    }\n\n    fn get_at(&self, idx: usize) -> Option<RuntimeValue> {\n        self.get().get(idx).cloned()\n    }\n\n    fn append(&self, val: RuntimeValue) {\n        self.get_mut().push(val)\n    }\n\n    fn pop(&self) {\n        self.get_mut().pop();\n    }\n\n    fn set_at(&self, idx: usize, val: RuntimeValue) -> Result<(), VmErrorReason> {\n        match idx.cmp(&self.len()) {\n            std::cmp::Ordering::Less => {\n                self.get_mut()[idx] = val;\n                Ok(())\n            }\n            std::cmp::Ordering::Equal => {\n                self.append(val);\n                Ok(())\n            }\n            std::cmp::Ordering::Greater => Err(VmErrorReason::IndexOutOfBounds(idx)),\n        }\n    }\n\n    fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.boxx.read(builtins, name)\n    }\n\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.boxx.list_attributes(builtins)\n    }\n}\n\nimpl std::fmt::Debug for ListImpl {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let li = self.get();\n        write!(\n            f,\n            \"[{}]\",\n            li.iter()\n                .map(|x| format!(\"{x:?}\"))\n                .collect::<Vec<String>>()\n                .join(\",\")\n        )\n    }\n}\n\n#[derive(Clone, Default)]\npub struct List {\n    pub(super) imp: Rc<ListImpl>,\n}\n\nimpl List {\n    pub fn from(values: &[RuntimeValue]) -> Self {\n        let ret = Self::default();\n        values.iter().cloned().for_each(|v| ret.append(v));\n        ret\n    }\n\n    pub fn new_with_capacity(cap: usize) -> Self {\n        Self {\n            imp: Rc::new(ListImpl::new_with_capacity(cap)),\n        }\n    }\n\n    pub fn len(&self) -> usize {\n        self.imp.len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.imp.is_empty()\n    }\n\n    pub fn get_at(&self, idx: usize) -> Option<RuntimeValue> {\n        self.imp.get_at(idx)\n    }\n\n    pub fn append(&self, val: RuntimeValue) {\n        self.imp.append(val)\n    }\n\n    pub fn pop(&self) {\n        self.imp.pop()\n    }\n\n    pub fn set_at(&self, idx: usize, val: RuntimeValue) -> Result<(), VmErrorReason> {\n        self.imp.set_at(idx, val)\n    }\n\n    pub fn read_index(\n        &self,\n        idx: &RuntimeValue,\n        _: &mut Frame,\n        _: &mut VirtualMachine,\n    ) -> Result<RuntimeValue, VmError> {\n        if let Some(i) = idx.as_integer() {\n            match self.get_at(*i.raw_value() as usize) {\n                Some(val) => Ok(val),\n                _ => Err(VmErrorReason::IndexOutOfBounds(*i.raw_value() as usize).into()),\n            }\n        } else {\n            Err(VmErrorReason::UnexpectedType.into())\n        }\n    }\n\n    pub fn write_index(\n        &self,\n        idx: &RuntimeValue,\n        val: &RuntimeValue,\n        _: &mut Frame,\n        _: &mut VirtualMachine,\n    ) -> ExecutionResult {\n        if let Some(i) = idx.as_integer() {\n            self.set_at(*i.raw_value() as usize, val.clone())?;\n            Ok(())\n        } else {\n            Err(VmErrorReason::UnexpectedType.into())\n        }\n    }\n\n    pub fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.read(builtins, name)\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n}\n\nimpl std::fmt::Debug for List {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{:?}\", self.imp)\n    }\n}\n\nimpl PartialEq for List {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for List {}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/mixin.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::RefCell, rc::Rc};\n\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{builtins::VmGlobals, runtime_value::object::ObjectBox, symbol::Symbol};\n\nuse super::RuntimeValue;\n\npub(super) struct MixinImpl {\n    name: String,\n    pub(super) entries: ObjectBox,\n    mixins: RefCell<crate::mixin_includer::MixinIncluder>,\n}\n\nimpl MixinImpl {\n    fn new(name: &str) -> Self {\n        Self {\n            name: name.to_owned(),\n            entries: ObjectBox::default(),\n            mixins: RefCell::new(crate::mixin_includer::MixinIncluder::default()),\n        }\n    }\n\n    fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        if let Some(val) = self.entries.read(builtins, name) {\n            Some(val.clone())\n        } else {\n            self.mixins.borrow().load_named_value(builtins, name)\n        }\n    }\n\n    fn named_values(&self, builtins: &VmGlobals) -> Vec<Symbol> {\n        self.entries.list_attributes(builtins).into_iter().collect()\n    }\n\n    fn include_mixin(&self, mixin: &Mixin) {\n        self.mixins.borrow_mut().include(mixin.clone());\n    }\n\n    fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.mixins.borrow().contains(mixin)\n    }\n\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        let mut attrs = self.entries.list_attributes(builtins);\n        attrs.extend(self.mixins.borrow().list_attributes(builtins));\n        attrs\n    }\n}\n\n#[derive(Clone)]\npub struct Mixin {\n    pub(super) imp: Rc<MixinImpl>,\n}\n\nimpl Mixin {\n    pub fn new(name: &str) -> Self {\n        Self {\n            imp: Rc::new(MixinImpl::new(name)),\n        }\n    }\n\n    pub fn name(&self) -> &str {\n        &self.imp.name\n    }\n\n    pub fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.load_named_value(builtins, name)\n    }\n\n    pub fn named_values(&self, builtins: &VmGlobals) -> Vec<Symbol> {\n        self.imp.named_values(builtins)\n    }\n\n    pub fn include_mixin(&self, mixin: &Mixin) {\n        self.imp.include_mixin(mixin);\n    }\n\n    pub fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self == mixin || self.imp.isa_mixin(mixin)\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n}\n\nimpl PartialEq for Mixin {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for Mixin {}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/mod.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse std::rc::Rc;\n\nuse aria_compiler::constant_value::ConstantValue;\nuse boolean::BooleanValue;\nuse bound_function::BoundFunction;\nuse enum_as_inner::EnumAsInner;\nuse enum_case::EnumValue;\nuse enumeration::Enum;\nuse float::FloatValue;\nuse function::Function;\nuse haxby_opcodes::BuiltinTypeId;\nuse integer::IntegerValue;\nuse kind::RuntimeValueType;\nuse list::List;\nuse mixin::Mixin;\nuse object::Object;\nuse opaque::OpaqueValue;\nuse runtime_code_object::CodeObject;\nuse rust_native_type::RustNativeType;\nuse string::StringValue;\nuse structure::Struct;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::vm_error::VmErrorReason,\n    frame::Frame,\n    runtime_module::RuntimeModule,\n    runtime_value::isa::IsaCheckable,\n    symbol::{\n        INTERNED_OP_IMPL_CALL, INTERNED_OP_IMPL_EQUALS, INTERNED_OP_IMPL_READ_INDEX,\n        INTERNED_OP_IMPL_WRITE_INDEX, INTERNED_OP_PRETTYPRINT, Symbol,\n    },\n    vm::{ExecutionResult, VirtualMachine},\n};\n\npub mod boolean;\npub mod bound_function;\npub mod builtin_value;\npub mod enum_case;\npub mod enumeration;\npub mod float;\npub mod function;\npub mod integer;\npub mod isa;\npub mod kind;\npub mod list;\npub mod mixin;\npub mod object;\npub mod opaque;\npub mod runtime_code_object;\npub mod rust_native_type;\npub mod string;\npub mod structure;\n\n#[derive(EnumAsInner, Clone)]\npub enum RuntimeValue {\n    Integer(IntegerValue),\n    String(StringValue),\n    Float(FloatValue),\n    Boolean(BooleanValue),\n    Object(Object),\n    EnumValue(EnumValue),\n    CodeObject(CodeObject),\n    Function(Function),\n    BoundFunction(BoundFunction),\n    List(List),\n    Mixin(Mixin),\n    Type(RuntimeValueType),\n    Module(RuntimeModule),\n    Opaque(OpaqueValue),\n    TypeCheck(IsaCheckable),\n}\n\nimpl RuntimeValue {\n    pub fn builtin_equals(\n        &self,\n        other: &Self,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> bool {\n        match (self, other) {\n            (Self::Integer(l0), Self::Integer(r0)) => l0 == r0,\n            (Self::Float(l0), Self::Float(r0)) => l0 == r0,\n            (Self::Float(l0), Self::Integer(r0)) => l0 == r0,\n            (Self::Integer(l0), Self::Float(r0)) => l0 == r0,\n            (Self::Boolean(l0), Self::Boolean(r0)) => l0 == r0,\n            (Self::String(l0), Self::String(r0)) => l0 == r0,\n            (Self::Object(l0), Self::Object(r0)) => l0 == r0,\n            (Self::Mixin(l0), Self::Mixin(r0)) => l0 == r0,\n            (Self::Module(l0), Self::Module(r0)) => l0 == r0,\n            (Self::EnumValue(l0), Self::EnumValue(r0)) => l0.builtin_equals(r0, cur_frame, vm),\n            (Self::CodeObject(l0), Self::CodeObject(r0)) => l0 == r0,\n            (Self::Function(l0), Self::Function(r0)) => l0 == r0,\n            (Self::BoundFunction(l0), Self::BoundFunction(r0)) => l0 == r0,\n            (Self::List(l0), Self::List(r0)) => l0 == r0,\n            (Self::Type(l0), Self::Type(r0)) => l0 == r0,\n            (Self::TypeCheck(l0), Self::TypeCheck(r0)) => l0 == r0,\n            _ => false,\n        }\n    }\n}\n\npub(crate) enum OperatorEvalAttemptOutcome<SuccessType> {\n    Ok(SuccessType),\n    Exception(crate::error::exception::VmException),\n    Error(crate::error::vm_error::VmError),\n    NeedTryROperator,\n}\n\npub(crate) enum OperatorEvalOutcome<SuccessType> {\n    Ok(SuccessType),\n    Exception(crate::error::exception::VmException),\n    Error(crate::error::vm_error::VmError),\n}\n\nimpl RuntimeValue {\n    pub(crate) fn is_builtin_unimplemented(&self, vm: &mut VirtualMachine) -> bool {\n        if let Some(s) = self.as_object() {\n            let unimp = vm\n                .globals\n                .get_builtin_type_by_id(BuiltinTypeId::Unimplemented);\n            let unimplemented = unimp.as_struct().unwrap();\n            return s.get_struct() == unimplemented;\n        }\n\n        false\n    }\n\n    fn try_eval_rel_op(\n        rel_op_obj: RuntimeValue,\n        other_val: &RuntimeValue,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> OperatorEvalAttemptOutcome<bool> {\n        cur_frame.stack.push(other_val.clone());\n        match rel_op_obj.eval(1, cur_frame, vm, true) {\n            Ok(cr) => match cr {\n                CallResult::Ok(rv) => {\n                    if let Some(bl) = rv.as_boolean() {\n                        OperatorEvalAttemptOutcome::Ok(*bl.raw_value())\n                    } else {\n                        OperatorEvalAttemptOutcome::NeedTryROperator\n                    }\n                }\n                CallResult::Exception(e) => {\n                    if e.is_builtin_unimplemented(vm) {\n                        OperatorEvalAttemptOutcome::NeedTryROperator\n                    } else {\n                        OperatorEvalAttemptOutcome::Exception(e)\n                    }\n                }\n            },\n            Err(err) => OperatorEvalAttemptOutcome::Error(err),\n        }\n    }\n\n    fn try_eval_bin_op(\n        op_equals: RuntimeValue,\n        other_val: &RuntimeValue,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> OperatorEvalAttemptOutcome<RuntimeValue> {\n        cur_frame.stack.push(other_val.clone());\n        match op_equals.eval(1, cur_frame, vm, true) {\n            Ok(cr) => match cr {\n                CallResult::Ok(rv) => OperatorEvalAttemptOutcome::Ok(rv),\n                CallResult::Exception(e) => {\n                    if e.is_builtin_unimplemented(vm) {\n                        OperatorEvalAttemptOutcome::NeedTryROperator\n                    } else {\n                        OperatorEvalAttemptOutcome::Exception(e)\n                    }\n                }\n            },\n            Err(e) => OperatorEvalAttemptOutcome::Error(e),\n        }\n    }\n\n    fn try_eval_unary_op(\n        op: RuntimeValue,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> OperatorEvalAttemptOutcome<RuntimeValue> {\n        match op.eval(0, cur_frame, vm, true) {\n            Ok(cr) => match cr {\n                CallResult::Ok(rv) => OperatorEvalAttemptOutcome::Ok(rv),\n                CallResult::Exception(e) => {\n                    if e.is_builtin_unimplemented(vm) {\n                        OperatorEvalAttemptOutcome::NeedTryROperator\n                    } else {\n                        OperatorEvalAttemptOutcome::Exception(e)\n                    }\n                }\n            },\n            Err(e) => OperatorEvalAttemptOutcome::Error(e),\n        }\n    }\n\n    pub fn equals(\n        lhs: &RuntimeValue,\n        rhs: &RuntimeValue,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> bool {\n        if let Ok(op_equals) = lhs.read_attribute(INTERNED_OP_IMPL_EQUALS, &vm.globals) {\n            match RuntimeValue::try_eval_rel_op(op_equals, rhs, cur_frame, vm) {\n                OperatorEvalAttemptOutcome::Ok(val) => {\n                    return val;\n                }\n                OperatorEvalAttemptOutcome::Exception(_) => {\n                    return lhs.builtin_equals(rhs, cur_frame, vm);\n                }\n                OperatorEvalAttemptOutcome::Error(_) => {\n                    return lhs.builtin_equals(rhs, cur_frame, vm);\n                }\n                OperatorEvalAttemptOutcome::NeedTryROperator => {}\n            }\n        }\n\n        if RuntimeValueType::get_type(lhs, &vm.globals)\n            == RuntimeValueType::get_type(rhs, &vm.globals)\n        {\n            return lhs.builtin_equals(rhs, cur_frame, vm);\n        }\n\n        if let Ok(op_equals) = rhs.read_attribute(INTERNED_OP_IMPL_EQUALS, &vm.globals) {\n            return match RuntimeValue::try_eval_rel_op(op_equals, lhs, cur_frame, vm) {\n                OperatorEvalAttemptOutcome::Ok(val) => val,\n                OperatorEvalAttemptOutcome::Exception(_)\n                | OperatorEvalAttemptOutcome::Error(_)\n                | OperatorEvalAttemptOutcome::NeedTryROperator => {\n                    lhs.builtin_equals(rhs, cur_frame, vm)\n                }\n            };\n        }\n\n        lhs.builtin_equals(rhs, cur_frame, vm)\n    }\n}\n\nmacro_rules! rel_op_impl {\n    ($rust_fn_name: ident, $aria_fwd_sym: expr, $aria_rev_sym: expr) => {\n        impl RuntimeValue {\n            pub(crate) fn $rust_fn_name(\n                lhs: &RuntimeValue,\n                rhs: &RuntimeValue,\n                cur_frame: &mut Frame,\n                vm: &mut VirtualMachine,\n            ) -> OperatorEvalOutcome<RuntimeValue> {\n                if let Ok(op) = lhs.read_attribute($aria_fwd_sym, &vm.globals) {\n                    match RuntimeValue::try_eval_rel_op(op, rhs, cur_frame, vm) {\n                        OperatorEvalAttemptOutcome::Ok(rv) => {\n                            return OperatorEvalOutcome::Ok(RuntimeValue::Boolean(rv.into()));\n                        }\n                        OperatorEvalAttemptOutcome::Exception(e) => {\n                            return OperatorEvalOutcome::Exception(e);\n                        }\n                        OperatorEvalAttemptOutcome::Error(e) => {\n                            return OperatorEvalOutcome::Error(e);\n                        }\n                        OperatorEvalAttemptOutcome::NeedTryROperator => {}\n                    }\n                }\n\n                if RuntimeValueType::get_type(lhs, &vm.globals)\n                    == RuntimeValueType::get_type(rhs, &vm.globals)\n                {\n                    return OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into());\n                }\n\n                if let Ok(op) = rhs.read_attribute($aria_rev_sym, &vm.globals) {\n                    match RuntimeValue::try_eval_rel_op(op, lhs, cur_frame, vm) {\n                        OperatorEvalAttemptOutcome::Ok(rv) => {\n                            return OperatorEvalOutcome::Ok(RuntimeValue::Boolean(rv.into()));\n                        }\n                        OperatorEvalAttemptOutcome::Exception(e) => {\n                            OperatorEvalOutcome::Exception(e)\n                        }\n                        OperatorEvalAttemptOutcome::Error(e) => OperatorEvalOutcome::Error(e),\n                        OperatorEvalAttemptOutcome::NeedTryROperator => {\n                            OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into())\n                        }\n                    }\n                } else {\n                    OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into())\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! bin_op_impl {\n    ($rust_fn_name: ident, $aria_fwd_sym: expr, $aria_rev_sym: expr) => {\n        impl RuntimeValue {\n            pub(crate) fn $rust_fn_name(\n                lhs: &RuntimeValue,\n                rhs: &RuntimeValue,\n                cur_frame: &mut Frame,\n                vm: &mut VirtualMachine,\n            ) -> OperatorEvalOutcome<RuntimeValue> {\n                if let Ok(op) = lhs.read_attribute($aria_fwd_sym, &vm.globals) {\n                    match RuntimeValue::try_eval_bin_op(op, rhs, cur_frame, vm) {\n                        OperatorEvalAttemptOutcome::Ok(rv) => {\n                            return OperatorEvalOutcome::Ok(rv);\n                        }\n                        OperatorEvalAttemptOutcome::Exception(e) => {\n                            return OperatorEvalOutcome::Exception(e);\n                        }\n                        OperatorEvalAttemptOutcome::Error(e) => {\n                            return OperatorEvalOutcome::Error(e);\n                        }\n                        OperatorEvalAttemptOutcome::NeedTryROperator => {}\n                    }\n                }\n\n                if RuntimeValueType::get_type(lhs, &vm.globals)\n                    == RuntimeValueType::get_type(rhs, &vm.globals)\n                {\n                    return OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into());\n                }\n\n                if let Ok(op) = rhs.read_attribute($aria_rev_sym, &vm.globals) {\n                    match RuntimeValue::try_eval_bin_op(op, lhs, cur_frame, vm) {\n                        OperatorEvalAttemptOutcome::Ok(rv) => OperatorEvalOutcome::Ok(rv),\n                        OperatorEvalAttemptOutcome::Exception(e) => {\n                            OperatorEvalOutcome::Exception(e)\n                        }\n                        OperatorEvalAttemptOutcome::Error(e) => OperatorEvalOutcome::Error(e),\n                        OperatorEvalAttemptOutcome::NeedTryROperator => {\n                            OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into())\n                        }\n                    }\n                } else {\n                    OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into())\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! unary_op_impl {\n    ($rust_fn_name: ident, $aria_sym: expr) => {\n        impl RuntimeValue {\n            pub(crate) fn $rust_fn_name(\n                obj: &RuntimeValue,\n                cur_frame: &mut Frame,\n                vm: &mut VirtualMachine,\n            ) -> OperatorEvalOutcome<RuntimeValue> {\n                if let Ok(op) = obj.read_attribute($aria_sym, &vm.globals) {\n                    match RuntimeValue::try_eval_unary_op(op, cur_frame, vm) {\n                        OperatorEvalAttemptOutcome::Ok(rv) => OperatorEvalOutcome::Ok(rv),\n                        OperatorEvalAttemptOutcome::Exception(e) => {\n                            OperatorEvalOutcome::Exception(e)\n                        }\n                        OperatorEvalAttemptOutcome::Error(e) => OperatorEvalOutcome::Error(e),\n                        OperatorEvalAttemptOutcome::NeedTryROperator => {\n                            OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into())\n                        }\n                    }\n                } else {\n                    OperatorEvalOutcome::Error(VmErrorReason::UnexpectedType.into())\n                }\n            }\n        }\n    };\n}\n\nbin_op_impl!(\n    add,\n    crate::symbol::INTERNED_OP_IMPL_ADD,\n    crate::symbol::INTERNED_OP_IMPL_RADD\n);\nbin_op_impl!(\n    sub,\n    crate::symbol::INTERNED_OP_IMPL_SUB,\n    crate::symbol::INTERNED_OP_IMPL_RSUB\n);\nbin_op_impl!(\n    mul,\n    crate::symbol::INTERNED_OP_IMPL_MUL,\n    crate::symbol::INTERNED_OP_IMPL_RMUL\n);\nbin_op_impl!(\n    div,\n    crate::symbol::INTERNED_OP_IMPL_DIV,\n    crate::symbol::INTERNED_OP_IMPL_RDIV\n);\nbin_op_impl!(\n    rem,\n    crate::symbol::INTERNED_OP_IMPL_REM,\n    crate::symbol::INTERNED_OP_IMPL_RREM\n);\nbin_op_impl!(\n    leftshift,\n    crate::symbol::INTERNED_OP_IMPL_LSHIFT,\n    crate::symbol::INTERNED_OP_IMPL_RLSHIFT\n);\nbin_op_impl!(\n    rightshift,\n    crate::symbol::INTERNED_OP_IMPL_RSHIFT,\n    crate::symbol::INTERNED_OP_IMPL_RRSHIFT\n);\nbin_op_impl!(\n    bitwise_and,\n    crate::symbol::INTERNED_OP_IMPL_BWAND,\n    crate::symbol::INTERNED_OP_IMPL_RBWAND\n);\nbin_op_impl!(\n    bitwise_or,\n    crate::symbol::INTERNED_OP_IMPL_BWOR,\n    crate::symbol::INTERNED_OP_IMPL_RBWOR\n);\nbin_op_impl!(\n    xor,\n    crate::symbol::INTERNED_OP_IMPL_XOR,\n    crate::symbol::INTERNED_OP_IMPL_RXOR\n);\n\nrel_op_impl!(\n    less_than,\n    crate::symbol::INTERNED_OP_IMPL_LT,\n    crate::symbol::INTERNED_OP_IMPL_GT\n);\nrel_op_impl!(\n    greater_than,\n    crate::symbol::INTERNED_OP_IMPL_GT,\n    crate::symbol::INTERNED_OP_IMPL_LT\n);\n\nrel_op_impl!(\n    less_than_equal,\n    crate::symbol::INTERNED_OP_IMPL_LTEQ,\n    crate::symbol::INTERNED_OP_IMPL_GTEQ\n);\nrel_op_impl!(\n    greater_than_equal,\n    crate::symbol::INTERNED_OP_IMPL_GTEQ,\n    crate::symbol::INTERNED_OP_IMPL_LTEQ\n);\n\nunary_op_impl!(neg, crate::symbol::INTERNED_OP_IMPL_NEG);\n\nimpl std::fmt::Debug for RuntimeValue {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Integer(x) => write!(f, \"{}\", x.raw_value()),\n            Self::Float(x) => write!(f, \"{}\", x.raw_value()),\n            Self::Boolean(x) => write!(f, \"{}\", x.raw_value()),\n            Self::String(s) => write!(f, \"\\\"{}\\\"\", s.raw_value()),\n            Self::Object(o) => write!(f, \"<object of type {}>\", o.get_struct().name()),\n            Self::Opaque(_) => write!(f, \"<opaque>\"),\n            Self::Mixin(m) => write!(f, \"<mixin{}>\", m.name()),\n            Self::Module(_) => write!(f, \"<module>\"),\n            Self::EnumValue(v) => {\n                write!(\n                    f,\n                    \"<enum-value of type {} case {}>\",\n                    v.get_container_enum().name(),\n                    v.get_case_index(),\n                )\n            }\n            Self::CodeObject(co) => write!(f, \"{co:?}\"),\n            Self::Function(fnc) => write!(f, \"{fnc:?}\"),\n            Self::BoundFunction(_) => write!(f, \"<bound-function>\"),\n            Self::List(lt) => write!(f, \"{lt:?}\"),\n            Self::Type(t) => write!(f, \"type<{t:?}>\"),\n            Self::TypeCheck(t) => write!(f, \"type-check({t:?})\"),\n        }\n    }\n}\n\nimpl std::fmt::Display for RuntimeValue {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            RuntimeValue::String(s) => write!(f, \"{}\", s.raw_value()),\n            _ => (self as &dyn std::fmt::Debug).fmt(f),\n        }\n    }\n}\n\nimpl TryFrom<&ConstantValue> for RuntimeValue {\n    type Error = aria_compiler::bc_reader::DecodeError;\n\n    fn try_from(value: &ConstantValue) -> Result<Self, Self::Error> {\n        match value {\n            ConstantValue::Integer(n) => Ok(RuntimeValue::Integer(From::from(*n))),\n            ConstantValue::String(s) => Ok(RuntimeValue::String(s.to_owned().into())),\n            ConstantValue::CompiledCodeObject(s) => {\n                Ok(RuntimeValue::CodeObject(TryFrom::try_from(s)?))\n            }\n            ConstantValue::Float(f) => Ok(RuntimeValue::Float(f.raw_value().into())),\n        }\n    }\n}\n\n#[derive(Debug)]\npub enum AttributeError {\n    NoSuchAttribute,\n    InvalidFunctionBinding,\n    ValueHasNoAttributes,\n}\n\nimpl AttributeError {\n    pub fn to_vm_error_reason(&self, name: &str) -> VmErrorReason {\n        match self {\n            Self::NoSuchAttribute => VmErrorReason::NoSuchIdentifier(name.to_owned()),\n            Self::InvalidFunctionBinding => VmErrorReason::InvalidBinding,\n            Self::ValueHasNoAttributes => VmErrorReason::UnexpectedType,\n        }\n    }\n}\n\nmacro_rules! val_or_bound_func {\n    ($val: expr, $self: expr) => {\n        if let Some(rf) = $val.as_function() {\n            if rf.attribute().is_type_method() {\n                Err(AttributeError::InvalidFunctionBinding)\n            } else {\n                Ok($self.bind(rf.clone()))\n            }\n        } else {\n            Ok($val)\n        }\n    };\n}\n\npub type CallResult = crate::vm::RunloopExit<RuntimeValue>;\n\nimpl RuntimeValue {\n    pub fn bind(&self, f: Function) -> RuntimeValue {\n        RuntimeValue::BoundFunction(BoundFunction::bind(self.clone(), f))\n    }\n\n    pub fn as_struct(&self) -> Option<&Struct> {\n        self.as_type().and_then(|rt| rt.as_struct())\n    }\n\n    pub fn as_enum(&self) -> Option<&Enum> {\n        self.as_type().and_then(|rt| rt.as_enum())\n    }\n\n    pub fn is_struct(&self) -> bool {\n        self.as_struct().is_some()\n    }\n\n    pub fn is_enum(&self) -> bool {\n        self.as_enum().is_some()\n    }\n\n    pub fn as_rust_native(&self) -> Option<&RustNativeType> {\n        self.as_type().and_then(|rt| rt.as_rust_native())\n    }\n\n    pub fn as_opaque_concrete<T: 'static>(&self) -> Option<Rc<T>> {\n        self.as_opaque().and_then(|c| c.as_concrete_object::<T>())\n    }\n\n    pub fn is_builtin_type(&self) -> bool {\n        match self {\n            Self::Integer(_) | Self::String(_) | Self::Float(_) | Self::Boolean(_) => true,\n            Self::Object(_)\n            | Self::EnumValue(_)\n            | Self::CodeObject(_)\n            | Self::Function(_)\n            | Self::BoundFunction(_)\n            | Self::List(_)\n            | Self::Mixin(_)\n            | Self::Type(_)\n            | Self::Module(_)\n            | Self::Opaque(_)\n            | Self::TypeCheck(_) => false,\n        }\n    }\n\n    pub fn get_builtin_type_id(&self) -> Option<BuiltinTypeId> {\n        match self {\n            Self::Integer(x) => Some(x.builtin_type_id()),\n            Self::String(x) => Some(x.builtin_type_id()),\n            Self::Float(x) => Some(x.builtin_type_id()),\n            Self::Boolean(x) => Some(x.builtin_type_id()),\n            Self::Object(_)\n            | Self::EnumValue(_)\n            | Self::CodeObject(_)\n            | Self::Function(_)\n            | Self::BoundFunction(_)\n            | Self::List(_)\n            | Self::Mixin(_)\n            | Self::Type(_)\n            | Self::Module(_)\n            | Self::Opaque(_)\n            | Self::TypeCheck(_) => None,\n        }\n    }\n\n    pub fn eval(\n        &self,\n        argc: u8,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n        discard_result: bool,\n    ) -> ExecutionResult<CallResult> {\n        if let Some(f) = self.as_function() {\n            f.eval(argc, cur_frame, vm, &Default::default(), discard_result)\n        } else if let Some(bf) = self.as_bound_function() {\n            bf.eval(argc, cur_frame, vm, discard_result)\n        } else {\n            match self.read_attribute(INTERNED_OP_IMPL_CALL, &vm.globals) {\n                Ok(op_call) => op_call.eval(argc, cur_frame, vm, discard_result),\n                _ => Err(crate::error::vm_error::VmErrorReason::UnexpectedType.into()),\n            }\n        }\n    }\n\n    pub fn prettyprint(&self, cur_frame: &mut Frame, vm: &mut VirtualMachine) -> String {\n        if let Ok(ppf) = self.read_attribute(INTERNED_OP_PRETTYPRINT, &vm.globals)\n            && ppf.eval(0, cur_frame, vm, false).is_ok()\n        {\n            // either check that the stack is doing ok - or have eval return the value\n            if let Some(val) = cur_frame.stack.try_pop()\n                && let Some(sv) = val.as_string()\n            {\n                return sv.raw_value().clone();\n            }\n        }\n\n        format!(\"{self}\")\n    }\n\n    fn get_attribute_store(&self) -> Option<&object::ObjectBox> {\n        match self {\n            RuntimeValue::Integer(bv) => Some(&bv.imp.as_ref().boxx),\n            RuntimeValue::String(bv) => Some(&bv.imp.as_ref().boxx),\n            RuntimeValue::Float(bv) => Some(&bv.imp.as_ref().boxx),\n            RuntimeValue::Boolean(bv) => Some(&bv.imp.as_ref().boxx),\n            RuntimeValue::Object(obj) => Some(&obj.imp.as_ref().boxx),\n            RuntimeValue::EnumValue(_) => None,\n            RuntimeValue::CodeObject(_) => None,\n            RuntimeValue::Function(f) => Some(f.get_attribute_store()),\n            RuntimeValue::BoundFunction(_) => None,\n            RuntimeValue::List(l) => Some(&l.imp.as_ref().boxx),\n            RuntimeValue::Mixin(m) => Some(&m.imp.as_ref().entries),\n            RuntimeValue::Type(t) => t.get_attribute_store(),\n            RuntimeValue::Module(_) => None,\n            RuntimeValue::Opaque(_) => None,\n            RuntimeValue::TypeCheck(_) => None,\n        }\n    }\n\n    pub fn write_attribute(\n        &self,\n        attrib_sym: Symbol,\n        val: RuntimeValue,\n        builtins: &mut VmGlobals,\n    ) -> Result<(), AttributeError> {\n        if let Some(rm) = self.as_module()\n            && let Some(attr_name) = builtins.resolve_symbol(attrib_sym)\n        {\n            rm.store_named_value(attr_name, val);\n            Ok(())\n        } else if let Some(ob) = self.get_attribute_store() {\n            ob.write(builtins, attrib_sym, val);\n            Ok(())\n        } else {\n            Err(AttributeError::ValueHasNoAttributes)\n        }\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> Vec<String> {\n        let mut resolved = rustc_data_structures::fx::FxHashSet::default();\n        let mut push_resolved = |symbols: rustc_data_structures::fx::FxHashSet<Symbol>| {\n            for sym in symbols {\n                if let Some(name) = builtins.resolve_symbol(sym) {\n                    resolved.insert(name.to_owned());\n                }\n            }\n        };\n\n        if let Some(obj) = self.as_object() {\n            let mut attrs = obj.list_attributes(builtins);\n            attrs.extend(obj.get_struct().list_attributes(builtins));\n            push_resolved(attrs);\n        } else if let Some(mixin) = self.as_mixin() {\n            push_resolved(mixin.list_attributes(builtins));\n        } else if let Some(enumm) = self.as_enum_value() {\n            push_resolved(enumm.get_container_enum().list_attributes(builtins));\n        } else if let Some(i) = self.as_integer() {\n            let mut attrs = i.list_attributes(builtins);\n            let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Int);\n            attrs.extend(bt.list_attributes(builtins));\n            push_resolved(attrs);\n        } else if let Some(i) = self.as_float() {\n            let mut attrs = i.list_attributes(builtins);\n            let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Float);\n            attrs.extend(bt.list_attributes(builtins));\n            push_resolved(attrs);\n        } else if let Some(s) = self.as_string() {\n            let mut attrs = s.list_attributes(builtins);\n            let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::String);\n            attrs.extend(bt.list_attributes(builtins));\n            push_resolved(attrs);\n        } else if let Some(b) = self.as_boolean() {\n            let mut attrs = b.list_attributes(builtins);\n            let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Bool);\n            attrs.extend(bt.list_attributes(builtins));\n            push_resolved(attrs);\n        } else if let Some(l) = self.as_list() {\n            let mut attrs = l.list_attributes(builtins);\n            let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::List);\n            attrs.extend(bt.list_attributes(builtins));\n            push_resolved(attrs);\n        } else if let Some(f) = self.as_function() {\n            push_resolved(f.list_attributes(builtins));\n        } else if let Some(m) = self.as_module() {\n            resolved.extend(m.list_named_values());\n        } else {\n            return vec![];\n        }\n\n        resolved.into_iter().collect()\n    }\n\n    pub(crate) fn read_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        slot_id: crate::shape::SlotId,\n        sid: crate::shape::ShapeId,\n    ) -> Option<RuntimeValue> {\n        match self {\n            RuntimeValue::Object(object) => match object.read_slot(slot_id, sid) {\n                Some(val) => Some(val),\n                None => val_or_bound_func!(object.get_struct().read_slot(slot_id, sid)?, self).ok(),\n            },\n            RuntimeValue::Mixin(mixin) => mixin.imp.as_ref().entries.read_slot(slot_id, sid),\n            RuntimeValue::EnumValue(enumm) => {\n                let val = enumm\n                    .get_container_enum()\n                    .imp\n                    .as_ref()\n                    .entries\n                    .read_slot(slot_id, sid)?;\n                val_or_bound_func!(val, self).ok()\n            }\n            RuntimeValue::Integer(bv) => match bv.imp.as_ref().boxx.read_slot(slot_id, sid) {\n                Some(val) => val_or_bound_func!(val, self).ok(),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Int);\n                    Self::read_slot_from_type(&bt, slot_id, sid)\n                        .and_then(|val| val_or_bound_func!(val, self).ok())\n                }\n            },\n            RuntimeValue::String(bv) => match bv.imp.as_ref().boxx.read_slot(slot_id, sid) {\n                Some(val) => val_or_bound_func!(val, self).ok(),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::String);\n                    Self::read_slot_from_type(&bt, slot_id, sid)\n                        .and_then(|val| val_or_bound_func!(val, self).ok())\n                }\n            },\n            RuntimeValue::Float(bv) => match bv.imp.as_ref().boxx.read_slot(slot_id, sid) {\n                Some(val) => val_or_bound_func!(val, self).ok(),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Float);\n                    Self::read_slot_from_type(&bt, slot_id, sid)\n                        .and_then(|val| val_or_bound_func!(val, self).ok())\n                }\n            },\n            RuntimeValue::Boolean(bv) => match bv.imp.as_ref().boxx.read_slot(slot_id, sid) {\n                Some(val) => val_or_bound_func!(val, self).ok(),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Bool);\n                    Self::read_slot_from_type(&bt, slot_id, sid)\n                        .and_then(|val| val_or_bound_func!(val, self).ok())\n                }\n            },\n            RuntimeValue::Function(f) => f.get_attribute_store().read_slot(slot_id, sid),\n            RuntimeValue::List(l) => match l.imp.as_ref().boxx.read_slot(slot_id, sid) {\n                Some(val) => Some(val),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::List);\n                    Self::read_slot_from_type(&bt, slot_id, sid)\n                        .and_then(|val| val_or_bound_func!(val, self).ok())\n                }\n            },\n            RuntimeValue::Type(t) => {\n                let val = Self::read_slot_from_type(t, slot_id, sid)?;\n                if let Some(rf) = val.as_function() {\n                    if !rf.attribute().is_type_method() {\n                        None\n                    } else {\n                        Some(self.bind(rf.clone()))\n                    }\n                } else {\n                    Some(val)\n                }\n            }\n            _ => None,\n        }\n    }\n\n    fn read_slot_from_type(\n        ty: &RuntimeValueType,\n        slot_id: crate::shape::SlotId,\n        sid: crate::shape::ShapeId,\n    ) -> Option<RuntimeValue> {\n        match ty {\n            RuntimeValueType::Struct(st) => st.imp.as_ref().entries.read_slot(slot_id, sid),\n            RuntimeValueType::Enum(en) => en.imp.as_ref().entries.read_slot(slot_id, sid),\n            RuntimeValueType::RustNative(rt) => rt.get_boxx().as_ref().read_slot(slot_id, sid),\n            _ => None,\n        }\n    }\n\n    fn resolve_to_slot_from_type(\n        ty: &RuntimeValueType,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, crate::shape::ShapeId, crate::shape::SlotId)> {\n        match ty {\n            RuntimeValueType::Struct(st) => st.imp.as_ref().entries.resolve_to_slot(builtins, name),\n            RuntimeValueType::Enum(en) => en.imp.as_ref().entries.resolve_to_slot(builtins, name),\n            RuntimeValueType::RustNative(rt) => {\n                rt.get_boxx().as_ref().resolve_to_slot(builtins, name)\n            }\n            _ => None,\n        }\n    }\n\n    pub(crate) fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, crate::shape::ShapeId, crate::shape::SlotId)> {\n        match self {\n            RuntimeValue::Object(object) => match object.resolve_to_slot(builtins, name) {\n                Some(val) => Some(val),\n                None => {\n                    let val = object.get_struct().resolve_to_slot(builtins, name)?;\n                    val_or_bound_func!(val.0, self)\n                        .ok()\n                        .map(|v| (v, val.1, val.2))\n                }\n            },\n            RuntimeValue::Mixin(mixin) => {\n                mixin.imp.as_ref().entries.resolve_to_slot(builtins, name)\n            }\n            RuntimeValue::EnumValue(enumm) => {\n                let val = enumm\n                    .get_container_enum()\n                    .imp\n                    .as_ref()\n                    .entries\n                    .resolve_to_slot(builtins, name)?;\n                val_or_bound_func!(val.0, self)\n                    .ok()\n                    .map(|v| (v, val.1, val.2))\n            }\n            RuntimeValue::Integer(bv) => match bv.imp.as_ref().boxx.resolve_to_slot(builtins, name)\n            {\n                Some(val) => val_or_bound_func!(val.0, self)\n                    .ok()\n                    .map(|v| (v, val.1, val.2)),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Int);\n                    let val = Self::resolve_to_slot_from_type(&bt, builtins, name)?;\n                    val_or_bound_func!(val.0, self)\n                        .ok()\n                        .map(|v| (v, val.1, val.2))\n                }\n            },\n            RuntimeValue::String(bv) => {\n                match bv.imp.as_ref().boxx.resolve_to_slot(builtins, name) {\n                    Some(val) => val_or_bound_func!(val.0, self)\n                        .ok()\n                        .map(|v| (v, val.1, val.2)),\n                    None => {\n                        let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::String);\n                        let val = Self::resolve_to_slot_from_type(&bt, builtins, name)?;\n                        val_or_bound_func!(val.0, self)\n                            .ok()\n                            .map(|v| (v, val.1, val.2))\n                    }\n                }\n            }\n            RuntimeValue::Float(bv) => match bv.imp.as_ref().boxx.resolve_to_slot(builtins, name) {\n                Some(val) => val_or_bound_func!(val.0, self)\n                    .ok()\n                    .map(|v| (v, val.1, val.2)),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Float);\n                    let val = Self::resolve_to_slot_from_type(&bt, builtins, name)?;\n                    val_or_bound_func!(val.0, self)\n                        .ok()\n                        .map(|v| (v, val.1, val.2))\n                }\n            },\n            RuntimeValue::Boolean(bv) => match bv.imp.as_ref().boxx.resolve_to_slot(builtins, name)\n            {\n                Some(val) => val_or_bound_func!(val.0, self)\n                    .ok()\n                    .map(|v| (v, val.1, val.2)),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::Bool);\n                    let val = Self::resolve_to_slot_from_type(&bt, builtins, name)?;\n                    val_or_bound_func!(val.0, self)\n                        .ok()\n                        .map(|v| (v, val.1, val.2))\n                }\n            },\n            RuntimeValue::Function(f) => f.get_attribute_store().resolve_to_slot(builtins, name),\n            RuntimeValue::List(l) => match l.imp.as_ref().boxx.resolve_to_slot(builtins, name) {\n                Some(val) => Some(val),\n                None => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::List);\n                    let val = Self::resolve_to_slot_from_type(&bt, builtins, name)?;\n                    val_or_bound_func!(val.0, self)\n                        .ok()\n                        .map(|v| (v, val.1, val.2))\n                }\n            },\n            RuntimeValue::Type(t) => {\n                let val = Self::resolve_to_slot_from_type(t, builtins, name)?;\n                if let Some(rf) = val.0.as_function() {\n                    if !rf.attribute().is_type_method() {\n                        None\n                    } else {\n                        Some((self.bind(rf.clone()), val.1, val.2))\n                    }\n                } else {\n                    Some(val)\n                }\n            }\n            _ => None,\n        }\n    }\n\n    pub fn read_attribute(\n        &self,\n        attrib_sym: Symbol,\n        builtins: &VmGlobals,\n    ) -> Result<RuntimeValue, AttributeError> {\n        if let Some(m) = self.as_module()\n            && let Some(attrib_name) = builtins.resolve_symbol(attrib_sym)\n        {\n            return match m.load_named_value(attrib_name) {\n                Some(v) => Ok(v),\n                None => Err(AttributeError::NoSuchAttribute),\n            };\n        }\n\n        if let Some(obj) = self.as_object() {\n            match obj.read(builtins, attrib_sym) {\n                Some(val) => Ok(val),\n                _ => match obj.get_struct().load_named_value(builtins, attrib_sym) {\n                    Some(val) => {\n                        val_or_bound_func!(val, self)\n                    }\n                    _ => Err(AttributeError::NoSuchAttribute),\n                },\n            }\n        } else if let Some(mixin) = self.as_mixin() {\n            match mixin.load_named_value(builtins, attrib_sym) {\n                Some(val) => Ok(val),\n                _ => Err(AttributeError::NoSuchAttribute),\n            }\n        } else if let Some(enumm) = self.as_enum_value() {\n            match enumm.read(builtins, attrib_sym) {\n                Some(val) => {\n                    val_or_bound_func!(val, self)\n                }\n                _ => Err(AttributeError::NoSuchAttribute),\n            }\n        } else if let Some(bt_id) = self.get_builtin_type_id() {\n            if let Some(attr_store) = self.get_attribute_store()\n                && let Some(val) = attr_store.read(builtins, attrib_sym)\n            {\n                val_or_bound_func!(val, self)\n            } else {\n                let bt = builtins.get_builtin_type_by_id(bt_id);\n                match bt.read_attribute(builtins, attrib_sym) {\n                    Ok(val) => {\n                        val_or_bound_func!(val, self)\n                    }\n                    _ => Err(AttributeError::NoSuchAttribute),\n                }\n            }\n        } else if let Some(f) = self.as_function() {\n            match f.read(builtins, attrib_sym) {\n                Some(val) => Ok(val),\n                _ => Err(AttributeError::NoSuchAttribute),\n            }\n        } else if let Some(l) = self.as_list() {\n            match l.read(builtins, attrib_sym) {\n                Some(val) => Ok(val),\n                _ => {\n                    let bt = builtins.get_builtin_type_by_id(BuiltinTypeId::List);\n                    match bt.read_attribute(builtins, attrib_sym) {\n                        Ok(val) => {\n                            val_or_bound_func!(val, self)\n                        }\n                        _ => Err(AttributeError::NoSuchAttribute),\n                    }\n                }\n            }\n        } else if let Some(t) = self.as_type() {\n            let val = t.read_attribute(builtins, attrib_sym)?;\n            if let Some(rf) = val.as_function() {\n                if !rf.attribute().is_type_method() {\n                    Err(AttributeError::InvalidFunctionBinding)\n                } else {\n                    Ok(self.bind(rf.clone()))\n                }\n            } else {\n                Ok(val)\n            }\n        } else {\n            Err(AttributeError::ValueHasNoAttributes)\n        }\n    }\n\n    pub fn read_index(\n        &self,\n        indices: &[RuntimeValue],\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> ExecutionResult<CallResult> {\n        match self.read_attribute(INTERNED_OP_IMPL_READ_INDEX, &vm.globals) {\n            Ok(read_index) => {\n                for idx in indices.iter().rev() {\n                    cur_frame.stack.push(idx.clone());\n                }\n                read_index.eval(indices.len() as u8, cur_frame, vm, false)\n            }\n            _ => Err(VmErrorReason::UnexpectedType.into()),\n        }\n    }\n\n    pub fn write_index(\n        &self,\n        indices: &[RuntimeValue],\n        val: &RuntimeValue,\n        cur_frame: &mut Frame,\n        vm: &mut VirtualMachine,\n    ) -> ExecutionResult<CallResult> {\n        match self.read_attribute(INTERNED_OP_IMPL_WRITE_INDEX, &vm.globals) {\n            Ok(write_index) => {\n                cur_frame.stack.push(val.clone());\n                for idx in indices.iter().rev() {\n                    cur_frame.stack.push(idx.clone());\n                }\n                write_index.eval(1 + indices.len() as u8, cur_frame, vm, true)\n            }\n            _ => Err(VmErrorReason::UnexpectedType.into()),\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/object.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{\n    cell::{Cell, UnsafeCell},\n    rc::Rc,\n};\n\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{error::vm_error::VmErrorReason, shape::ShapeId};\nuse crate::{shape::SlotId, symbol::Symbol};\n\nuse super::{RuntimeValue, structure::Struct};\n\npub struct ObjectBox {\n    shape: Cell<ShapeId>,\n    slots: UnsafeCell<Vec<RuntimeValue>>,\n}\n\nimpl Default for ObjectBox {\n    fn default() -> Self {\n        Self {\n            shape: Cell::new(crate::shape::Shapes::EMPTY_SHAPE_INDEX),\n            slots: UnsafeCell::new(Vec::new()),\n        }\n    }\n}\n\nimpl ObjectBox {\n    #[allow(clippy::mut_from_ref)]\n    #[inline]\n    fn get(&self) -> &Vec<RuntimeValue> {\n        unsafe { &*self.slots.get() }\n    }\n\n    #[allow(clippy::mut_from_ref)]\n    #[inline]\n    fn get_mut(&self) -> &mut Vec<RuntimeValue> {\n        unsafe { &mut *self.slots.get() }\n    }\n\n    pub fn write(\n        &self,\n        builtins: &mut crate::builtins::VmGlobals,\n        name: Symbol,\n        val: RuntimeValue,\n    ) {\n        let (shape_id, slot_id) = builtins.shapes.transition(self.shape.get(), name);\n        self.shape.set(shape_id);\n        let slot_id = slot_id.0 as usize;\n        let slot_count = self.get().len();\n        if slot_id == slot_count {\n            self.get_mut().push(val);\n        } else if slot_id < slot_count {\n            self.get_mut()[slot_id] = val;\n        } else {\n            panic!(\"slots should grow sequentially\");\n        }\n    }\n\n    pub fn read(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<RuntimeValue> {\n        let slot_id = builtins.shapes.resolve_slot(self.shape.get(), name)?;\n        self.get().get(slot_id.0 as usize).cloned()\n    }\n\n    pub(super) fn read_slot(&self, slot_id: SlotId, sid: ShapeId) -> Option<RuntimeValue> {\n        if self.shape.get() != sid {\n            return None;\n        }\n        self.get().get(slot_id.0 as usize).cloned()\n    }\n\n    pub(super) fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, ShapeId, SlotId)> {\n        let sid = self.shape.get();\n        let slot_id = builtins.shapes.resolve_slot(sid, name)?;\n        let val = self.get().get(slot_id.0 as usize)?.clone();\n        Some((val, sid, slot_id))\n    }\n\n    pub(super) fn list_attributes(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n    ) -> FxHashSet<Symbol> {\n        let mut ret = FxHashSet::<Symbol>::default();\n        let shape = match builtins.shapes.get_shape(self.shape.get()) {\n            Some(s) => s,\n            None => return ret,\n        };\n\n        assert_eq!(self.get().len(), shape.reverse_slots.len());\n\n        shape.reverse_slots.iter().for_each(|&sym| {\n            ret.insert(sym);\n        });\n        ret\n    }\n\n    pub(crate) fn contains(&self, builtins: &crate::builtins::VmGlobals, name: Symbol) -> bool {\n        let slot_count = self.get().len();\n        if let Some(slot_id) = builtins.shapes.resolve_slot(self.shape.get(), name) {\n            (slot_id.0 as usize) < slot_count\n        } else {\n            false\n        }\n    }\n}\n\npub(super) struct ObjectImpl {\n    pub(super) boxx: ObjectBox,\n    kind: Struct,\n}\n\n#[derive(Clone)]\npub struct Object {\n    pub(super) imp: Rc<ObjectImpl>,\n}\n\nimpl ObjectImpl {\n    fn new(kind: &Struct) -> Self {\n        Self {\n            boxx: Default::default(),\n            kind: kind.clone(),\n        }\n    }\n\n    fn read_slot(&self, slot_id: SlotId, sid: ShapeId) -> Option<RuntimeValue> {\n        self.boxx.read_slot(slot_id, sid)\n    }\n\n    fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, ShapeId, SlotId)> {\n        self.boxx.resolve_to_slot(builtins, name)\n    }\n\n    fn write(&self, builtins: &mut crate::builtins::VmGlobals, name: Symbol, val: RuntimeValue) {\n        self.boxx.write(builtins, name, val)\n    }\n\n    fn read(&self, builtins: &crate::builtins::VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.boxx.read(builtins, name)\n    }\n\n    fn list_attributes(&self, builtins: &crate::builtins::VmGlobals) -> FxHashSet<Symbol> {\n        self.boxx.list_attributes(builtins)\n    }\n}\n\nimpl Object {\n    pub fn new(kind: &Struct) -> Self {\n        Self {\n            imp: Rc::new(ObjectImpl::new(kind)),\n        }\n    }\n\n    pub(crate) fn read_slot(&self, slot_id: SlotId, sid: ShapeId) -> Option<RuntimeValue> {\n        self.imp.read_slot(slot_id, sid)\n    }\n\n    pub(crate) fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, ShapeId, SlotId)> {\n        self.imp.resolve_to_slot(builtins, name)\n    }\n\n    pub fn read(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<RuntimeValue> {\n        self.imp.read(builtins, name)\n    }\n\n    pub fn write(\n        &self,\n        builtins: &mut crate::builtins::VmGlobals,\n        name: Symbol,\n        val: RuntimeValue,\n    ) {\n        self.imp.write(builtins, name, val)\n    }\n\n    pub fn list_attributes(&self, builtins: &crate::builtins::VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n\n    pub fn get_struct(&self) -> &Struct {\n        &self.imp.kind\n    }\n\n    pub fn with_value(\n        self,\n        builtins: &mut crate::builtins::VmGlobals,\n        name: Symbol,\n        val: RuntimeValue,\n    ) -> Self {\n        self.imp.write(builtins, name, val);\n        self\n    }\n}\n\nimpl PartialEq for Object {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for Object {}\n\nimpl Object {\n    pub fn extract_field<FnType, OkType>(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n        f: FnType,\n    ) -> Result<OkType, VmErrorReason>\n    where\n        FnType: FnOnce(RuntimeValue) -> Option<OkType>,\n    {\n        let val = match self.read(builtins, name) {\n            Some(v) => v,\n            None => {\n                return Err(VmErrorReason::NoSuchIdentifier(name.to_string()));\n            }\n        };\n\n        match f(val) {\n            Some(v) => Ok(v),\n            None => Err(VmErrorReason::UnexpectedType),\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/opaque.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{any::Any, rc::Rc};\n\n#[derive(Clone)]\nstruct OpaqueValueImpl {\n    val: Rc<dyn Any>,\n}\n\n#[derive(Clone)]\npub struct OpaqueValue {\n    imp: OpaqueValueImpl,\n}\n\nimpl std::fmt::Debug for OpaqueValue {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"<opaque>\")\n    }\n}\n\nimpl std::fmt::Display for OpaqueValue {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"<opaque>\")\n    }\n}\n\nimpl OpaqueValue {\n    pub(crate) fn as_concrete_object<T: 'static>(&self) -> Option<Rc<T>> {\n        self.imp.val.clone().downcast::<T>().ok()\n    }\n\n    pub fn new<T: 'static>(x: T) -> Self {\n        Self {\n            imp: OpaqueValueImpl { val: Rc::new(x) },\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/runtime_code_object.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::rc::Rc;\n\nuse aria_compiler::{\n    bc_reader::{BytecodeReader, DecodeResult},\n    constant_value::CompiledCodeObject,\n    line_table::LineTable,\n};\nuse aria_parser::ast::SourcePointer;\nuse haxby_opcodes::Opcode;\n\n#[derive(Clone)]\npub struct CodeObject {\n    pub name: String,\n    pub attribute: u8,\n    pub body: Rc<[Opcode]>,\n    pub required_argc: u8,\n    pub default_argc: u8,\n    pub frame_size: u8,\n    pub loc: SourcePointer,\n    pub line_table: Rc<LineTable>,\n}\n\nimpl PartialEq for CodeObject {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.body, &other.body)\n    }\n}\n\nfn byte_array_to_opcode_array(bytes: &[u8]) -> DecodeResult<Vec<Opcode>> {\n    let mut opcodes = Vec::new();\n    let mut decoder = BytecodeReader::try_from(bytes)?;\n\n    loop {\n        let next = decoder.read_opcode();\n        match next {\n            Ok(op) => opcodes.push(op),\n            Err(err) => {\n                return match err {\n                    aria_compiler::bc_reader::DecodeError::EndOfStream => Ok(opcodes),\n                    _ => Err(err),\n                };\n            }\n        }\n    }\n}\n\nimpl TryFrom<&CompiledCodeObject> for CodeObject {\n    type Error = aria_compiler::bc_reader::DecodeError;\n\n    fn try_from(value: &CompiledCodeObject) -> Result<Self, Self::Error> {\n        let ops = byte_array_to_opcode_array(value.body.as_slice())?;\n        let body: Rc<[Opcode]> = ops.into();\n\n        Ok(Self {\n            name: value.name.clone(),\n            attribute: value.attribute,\n            body,\n            required_argc: value.required_argc,\n            default_argc: value.default_argc,\n            frame_size: value.frame_size,\n            loc: value.loc.clone(),\n            line_table: Rc::from(value.line_table.clone()),\n        })\n    }\n}\n\nimpl std::fmt::Debug for CodeObject {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"<code-object {} at {}>\", self.name, self.loc)\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/rust_native_type.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::RefCell, rc::Rc};\n\nuse enum_as_inner::EnumAsInner;\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{builtins::VmGlobals, symbol::Symbol};\n\nuse super::{\n    RuntimeValue,\n    function::{BuiltinFunctionImpl, Function},\n    mixin::Mixin,\n    object::ObjectBox,\n};\n\n#[derive(EnumAsInner, Clone, PartialEq, Eq)]\npub enum RustNativeValueKind {\n    Boolean,\n    Integer,\n    Float,\n    List,\n    String,\n    Type,\n}\n\nstruct RustNativeTypeImpl {\n    tag: RustNativeValueKind,\n    boxx: Rc<ObjectBox>,\n    mixins: RefCell<crate::mixin_includer::MixinIncluder>,\n}\n\nimpl RustNativeTypeImpl {\n    fn write(&self, builtins: &mut VmGlobals, name: Symbol, val: RuntimeValue) {\n        self.boxx.write(builtins, name, val)\n    }\n\n    fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        match self.boxx.read(builtins, name) {\n            Some(nv) => Some(nv),\n            _ => self.mixins.borrow().load_named_value(builtins, name),\n        }\n    }\n\n    fn include_mixin(&self, mixin: &Mixin) {\n        self.mixins.borrow_mut().include(mixin.clone());\n    }\n\n    fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.mixins.borrow().contains(mixin)\n    }\n\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        let mut attrs = self.boxx.list_attributes(builtins);\n        attrs.extend(self.mixins.borrow().list_attributes(builtins));\n        attrs\n    }\n}\n\n#[derive(Clone)]\npub struct RustNativeType {\n    imp: Rc<RustNativeTypeImpl>,\n}\n\nimpl RustNativeType {\n    pub fn new(rvt: RustNativeValueKind) -> Self {\n        Self {\n            imp: Rc::new(RustNativeTypeImpl {\n                tag: rvt,\n                boxx: Rc::new(Default::default()),\n                mixins: Default::default(),\n            }),\n        }\n    }\n\n    pub fn get_tag(&self) -> &RustNativeValueKind {\n        &self.imp.tag\n    }\n\n    pub fn get_boxx(&self) -> &Rc<ObjectBox> {\n        &self.imp.boxx\n    }\n\n    pub(crate) fn write(&self, builtins: &mut VmGlobals, name: Symbol, val: RuntimeValue) {\n        self.imp.write(builtins, name, val);\n    }\n\n    pub fn read(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.read(builtins, name)\n    }\n\n    pub fn include_mixin(&self, mixin: &Mixin) {\n        self.imp.include_mixin(mixin);\n    }\n\n    pub fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.imp.isa_mixin(mixin)\n    }\n\n    pub fn insert_builtin<T>(&self, builtins: &mut VmGlobals)\n    where\n        T: 'static + Default + BuiltinFunctionImpl,\n    {\n        let t = T::default();\n        let name = builtins\n            .intern_symbol(t.name())\n            .expect(\"too many symbols interned\");\n        self.get_boxx().write(\n            builtins,\n            name,\n            RuntimeValue::Function(Function::builtin_from(t)),\n        );\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n}\n\nimpl PartialEq for RustNativeType {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp) || self.imp.tag == other.imp.tag\n    }\n}\nimpl Eq for RustNativeType {}\n\nimpl std::fmt::Debug for RustNativeType {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self.get_tag() {\n            RustNativeValueKind::Boolean => write!(f, \"Bool\"),\n            RustNativeValueKind::Integer => write!(f, \"Int\"),\n            RustNativeValueKind::Float => write!(f, \"Float\"),\n            RustNativeValueKind::List => write!(f, \"List\"),\n            RustNativeValueKind::String => write!(f, \"String\"),\n            RustNativeValueKind::Type => write!(f, \"Type\"),\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/string.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\n\nuse crate::{error::vm_error::VmErrorReason, frame::Frame, vm::VirtualMachine};\n\nuse super::{RuntimeValue, builtin_value::BuiltinValue};\n\npub type StringValue = BuiltinValue<String>;\n\nimpl From<&str> for StringValue {\n    fn from(value: &str) -> Self {\n        From::from(value.to_owned())\n    }\n}\n\nimpl StringValue {\n    pub fn len(&self) -> usize {\n        self.imp.val.chars().count()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.imp.val.is_empty()\n    }\n\n    pub fn contains(&self, pat: &str) -> bool {\n        self.imp.val.contains(pat)\n    }\n}\n\nimpl std::ops::Add<&StringValue> for &StringValue {\n    type Output = StringValue;\n\n    fn add(self, rhs: &StringValue) -> Self::Output {\n        From::from(format!(\"{}{}\", self.raw_value(), rhs.raw_value()))\n    }\n}\n\nimpl PartialEq<StringValue> for StringValue {\n    fn eq(&self, other: &StringValue) -> bool {\n        self.raw_value() == other.raw_value()\n    }\n}\nimpl Eq for StringValue {}\n\nimpl PartialOrd<StringValue> for StringValue {\n    fn partial_cmp(&self, other: &StringValue) -> Option<std::cmp::Ordering> {\n        Some(self.cmp(other))\n    }\n}\nimpl Ord for StringValue {\n    fn cmp(&self, other: &Self) -> std::cmp::Ordering {\n        self.raw_value().cmp(other.raw_value())\n    }\n}\n\nimpl PartialEq<str> for StringValue {\n    fn eq(&self, other: &str) -> bool {\n        self.raw_value() == other\n    }\n}\n\nimpl StringValue {\n    pub fn get_at(&self, idx: usize) -> Option<RuntimeValue> {\n        self.raw_value()\n            .chars()\n            .nth(idx)\n            .map(|c| RuntimeValue::String(c.to_string().into()))\n    }\n\n    pub fn read_index(\n        &self,\n        idx: &RuntimeValue,\n        _: &mut Frame,\n        _: &mut VirtualMachine,\n    ) -> Result<RuntimeValue, VmErrorReason> {\n        if let Some(i) = idx.as_integer() {\n            match self.get_at(*i.raw_value() as usize) {\n                Some(val) => Ok(val),\n                _ => Err(VmErrorReason::IndexOutOfBounds(*i.raw_value() as usize)),\n            }\n        } else {\n            Err(VmErrorReason::UnexpectedType)\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/runtime_value/structure.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{cell::RefCell, rc::Rc};\n\nuse rustc_data_structures::fx::FxHashSet;\n\nuse crate::{\n    builtins::VmGlobals,\n    error::vm_error::VmErrorReason,\n    runtime_value::object::ObjectBox,\n    shape::{ShapeId, SlotId},\n    symbol::Symbol,\n};\n\nuse super::{\n    RuntimeValue,\n    function::{BuiltinFunctionImpl, Function},\n    mixin::Mixin,\n};\n\npub(super) struct StructImpl {\n    name: String,\n    pub(super) entries: ObjectBox,\n    mixins: RefCell<crate::mixin_includer::MixinIncluder>,\n}\n\nimpl StructImpl {\n    fn new(name: &str) -> Self {\n        Self {\n            name: name.to_owned(),\n            entries: ObjectBox::default(),\n            mixins: RefCell::new(crate::mixin_includer::MixinIncluder::default()),\n        }\n    }\n\n    fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.mixins.borrow().contains(mixin)\n    }\n\n    fn read_slot(&self, slot_id: SlotId, sid: ShapeId) -> Option<RuntimeValue> {\n        self.entries.read_slot(slot_id, sid)\n    }\n\n    fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, ShapeId, SlotId)> {\n        self.entries.resolve_to_slot(builtins, name)\n    }\n\n    fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        if let Some(nv) = self.entries.read(builtins, name) {\n            Some(nv.clone())\n        } else {\n            self.mixins.borrow().load_named_value(builtins, name)\n        }\n    }\n\n    fn store_named_value(&self, builtins: &mut VmGlobals, name: Symbol, val: RuntimeValue) {\n        self.entries.write(builtins, name, val);\n    }\n\n    fn include_mixin(&self, mixin: &Mixin) {\n        self.mixins.borrow_mut().include(mixin.clone());\n    }\n\n    fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        let mut attrs = self.entries.list_attributes(builtins);\n        attrs.extend(self.mixins.borrow().list_attributes(builtins));\n        attrs\n    }\n}\n\n#[derive(Clone)]\npub struct Struct {\n    pub(super) imp: Rc<StructImpl>,\n}\n\nimpl Struct {\n    pub fn new(name: &str) -> Self {\n        Self {\n            imp: Rc::new(StructImpl::new(name)),\n        }\n    }\n\n    pub fn name(&self) -> &str {\n        &self.imp.name\n    }\n\n    pub fn load_named_value(&self, builtins: &VmGlobals, name: Symbol) -> Option<RuntimeValue> {\n        self.imp.load_named_value(builtins, name)\n    }\n\n    pub fn include_mixin(&self, mixin: &Mixin) {\n        self.imp.include_mixin(mixin);\n    }\n\n    pub fn isa_mixin(&self, mixin: &Mixin) -> bool {\n        self.imp.isa_mixin(mixin)\n    }\n\n    pub fn list_attributes(&self, builtins: &VmGlobals) -> FxHashSet<Symbol> {\n        self.imp.list_attributes(builtins)\n    }\n}\n\nimpl PartialEq for Struct {\n    fn eq(&self, other: &Self) -> bool {\n        Rc::ptr_eq(&self.imp, &other.imp)\n    }\n}\nimpl Eq for Struct {}\n\nimpl Struct {\n    pub(crate) fn read_slot(&self, slot_id: SlotId, sid: ShapeId) -> Option<RuntimeValue> {\n        self.imp.read_slot(slot_id, sid)\n    }\n\n    pub(crate) fn resolve_to_slot(\n        &self,\n        builtins: &crate::builtins::VmGlobals,\n        name: Symbol,\n    ) -> Option<(RuntimeValue, ShapeId, SlotId)> {\n        self.imp.resolve_to_slot(builtins, name)\n    }\n\n    pub fn insert_builtin<T>(&self, builtins: &mut VmGlobals)\n    where\n        T: 'static + Default + BuiltinFunctionImpl,\n    {\n        let t = T::default();\n        let name = builtins\n            .intern_symbol(t.name())\n            .expect(\"too many symbols interned\");\n        self.imp.store_named_value(\n            builtins,\n            name,\n            RuntimeValue::Function(Function::builtin_from(t)),\n        );\n    }\n\n    pub fn extract_field<FnType, OkType>(\n        &self,\n        builtins: &VmGlobals,\n        name: Symbol,\n        f: FnType,\n    ) -> Result<OkType, VmErrorReason>\n    where\n        FnType: FnOnce(RuntimeValue) -> Option<OkType>,\n    {\n        let val = match self.load_named_value(builtins, name) {\n            Some(v) => v,\n            None => {\n                return Err(VmErrorReason::NoSuchIdentifier(name.to_string()));\n            }\n        };\n\n        match f(val) {\n            Some(v) => Ok(v),\n            None => Err(VmErrorReason::UnexpectedType),\n        }\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/shape.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse rustc_data_structures::fx::FxHashMap;\n\nuse crate::symbol::Symbol;\n\n#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]\npub struct ShapeId(pub u32);\n\n#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]\npub struct SlotId(pub u32);\n\npub struct Shape {\n    #[allow(unused)]\n    pub(crate) id: ShapeId,\n    pub(crate) slots: FxHashMap<Symbol, SlotId>,\n    pub(crate) reverse_slots: Vec<Symbol>,\n    pub(crate) transitions: FxHashMap<Symbol, ShapeId>,\n}\n\nimpl Shape {\n    pub fn empty() -> Self {\n        Shape {\n            id: Shapes::EMPTY_SHAPE_INDEX,\n            slots: Default::default(),\n            reverse_slots: Vec::default(),\n            transitions: Default::default(),\n        }\n    }\n}\n\npub struct Shapes {\n    shapes: Vec<Shape>,\n}\n\nimpl Default for Shapes {\n    fn default() -> Self {\n        Self {\n            shapes: vec![Shape::empty()],\n        }\n    }\n}\n\nimpl Shapes {\n    pub const EMPTY_SHAPE_INDEX: ShapeId = ShapeId(0);\n\n    pub fn transition(&mut self, cur_sid: ShapeId, name: Symbol) -> (ShapeId, SlotId) {\n        let cur_shape = &self.shapes[cur_sid.0 as usize];\n        if let Some(cur_slot) = cur_shape.slots.get(&name) {\n            return (cur_sid, *cur_slot);\n        }\n\n        if let Some(next_sid) = cur_shape.transitions.get(&name) {\n            let slot_id = self.shapes[next_sid.0 as usize]\n                .slots\n                .get(&name)\n                .expect(\"transition shape missing slot\");\n            return (*next_sid, *slot_id);\n        }\n\n        let new_slot_id = SlotId(cur_shape.slots.len() as u32);\n        let mut new_shape_slots = cur_shape.slots.clone();\n        new_shape_slots.insert(name, new_slot_id);\n        let mut new_shape_reverse_slots = cur_shape.reverse_slots.clone();\n        assert_eq!(new_shape_reverse_slots.len(), new_slot_id.0 as usize);\n        new_shape_reverse_slots.push(name);\n\n        let new_sid = ShapeId(self.shapes.len() as u32);\n        let new_shape = Shape {\n            id: new_sid,\n            slots: new_shape_slots,\n            reverse_slots: new_shape_reverse_slots,\n            transitions: FxHashMap::default(),\n        };\n        self.shapes.push(new_shape);\n\n        let cur_shape = &mut self.shapes[cur_sid.0 as usize];\n        cur_shape.transitions.insert(name, new_sid);\n\n        (new_sid, new_slot_id)\n    }\n\n    pub fn resolve_slot(&self, sid: ShapeId, name: Symbol) -> Option<SlotId> {\n        self.shapes\n            .get(sid.0 as usize)\n            .and_then(|shape| shape.slots.get(&name).copied())\n    }\n\n    pub fn resolve_symbol(&self, sid: ShapeId, slot_id: SlotId) -> Option<Symbol> {\n        self.shapes\n            .get(sid.0 as usize)\n            .and_then(|shape| shape.reverse_slots.get(slot_id.0 as usize).copied())\n    }\n\n    pub(crate) fn get_shape(&self, sid: ShapeId) -> Option<&Shape> {\n        self.shapes.get(sid.0 as usize)\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/stack.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\npub struct Stack<T>\nwhere\n    T: Clone,\n{\n    values: Vec<T>,\n}\n\nimpl<T> Default for Stack<T>\nwhere\n    T: Clone,\n{\n    fn default() -> Self {\n        Self {\n            values: Default::default(),\n        }\n    }\n}\n\nimpl<T> Stack<T>\nwhere\n    T: Clone,\n{\n    pub fn push(&mut self, val: T) {\n        self.values.push(val);\n    }\n\n    pub fn peek(&mut self) -> Option<&T> {\n        self.values.last()\n    }\n\n    pub fn try_pop(&mut self) -> Option<T> {\n        self.values.pop()\n    }\n\n    pub fn pop(&mut self) -> T {\n        self.try_pop().expect(\"empty stack\")\n    }\n\n    pub fn pop_count(&mut self, count: usize) -> Vec<T> {\n        let mut result = Vec::with_capacity(count);\n        for _ in 0..count {\n            if let Some(v) = self.try_pop() {\n                result.push(v);\n            } else {\n                break;\n            }\n        }\n\n        result\n    }\n\n    pub fn try_pop_if<F, U>(&mut self, f: F) -> Option<U>\n    where\n        F: FnOnce(T) -> Option<U>,\n    {\n        match self.try_pop() {\n            Some(t) => f(t),\n            None => None,\n        }\n    }\n\n    pub fn pop_if<F, U>(&mut self, f: F) -> Option<U>\n    where\n        F: FnOnce(T) -> Option<U>,\n    {\n        f(self.pop())\n    }\n\n    pub fn len(&self) -> usize {\n        self.values.len()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.values.is_empty()\n    }\n\n    pub fn clear(&mut self) {\n        self.values.clear();\n    }\n\n    pub fn peek_at_offset(&mut self, i: usize) -> Option<&T> {\n        let idx = self.len() - 1 - i;\n        self.values.get(idx)\n    }\n\n    pub fn contains(&self, val: &T) -> bool\n    where\n        T: PartialEq<T>,\n    {\n        self.values.iter().any(|x| val.eq(x))\n    }\n}\n\nimpl<T> Stack<T>\nwhere\n    T: Clone + std::fmt::Debug,\n{\n    pub fn dump(&self) {\n        let mut first = true;\n        self.values.iter().rev().for_each(|f| {\n            if first {\n                first = false;\n                println!(\"--> {f:?}\")\n            } else {\n                println!(\"{f:?}\")\n            };\n        });\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/symbol.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse rustc_data_structures::fx::FxHashMap;\nuse thiserror::Error;\n\n#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]\npub struct Symbol(pub u32);\n\nimpl std::fmt::Display for Symbol {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Symbol({})\", self.0)\n    }\n}\n\npub const INTERNED_OP_IMPL_CALL: Symbol = Symbol(0);\npub const INTERNED_OP_IMPL_EQUALS: Symbol = Symbol(1);\npub const INTERNED_OP_IMPL_READ_INDEX: Symbol = Symbol(2);\npub const INTERNED_OP_IMPL_WRITE_INDEX: Symbol = Symbol(3);\npub const INTERNED_OP_IMPL_ADD: Symbol = Symbol(4);\npub const INTERNED_OP_IMPL_RADD: Symbol = Symbol(5);\npub const INTERNED_OP_IMPL_SUB: Symbol = Symbol(6);\npub const INTERNED_OP_IMPL_RSUB: Symbol = Symbol(7);\npub const INTERNED_OP_IMPL_MUL: Symbol = Symbol(8);\npub const INTERNED_OP_IMPL_RMUL: Symbol = Symbol(9);\npub const INTERNED_OP_IMPL_DIV: Symbol = Symbol(10);\npub const INTERNED_OP_IMPL_RDIV: Symbol = Symbol(11);\npub const INTERNED_OP_IMPL_REM: Symbol = Symbol(12);\npub const INTERNED_OP_IMPL_RREM: Symbol = Symbol(13);\npub const INTERNED_OP_IMPL_LSHIFT: Symbol = Symbol(14);\npub const INTERNED_OP_IMPL_RLSHIFT: Symbol = Symbol(15);\npub const INTERNED_OP_IMPL_RSHIFT: Symbol = Symbol(16);\npub const INTERNED_OP_IMPL_RRSHIFT: Symbol = Symbol(17);\npub const INTERNED_OP_IMPL_BWAND: Symbol = Symbol(18);\npub const INTERNED_OP_IMPL_RBWAND: Symbol = Symbol(19);\npub const INTERNED_OP_IMPL_BWOR: Symbol = Symbol(20);\npub const INTERNED_OP_IMPL_RBWOR: Symbol = Symbol(21);\npub const INTERNED_OP_IMPL_XOR: Symbol = Symbol(22);\npub const INTERNED_OP_IMPL_RXOR: Symbol = Symbol(23);\npub const INTERNED_OP_IMPL_LT: Symbol = Symbol(24);\npub const INTERNED_OP_IMPL_GT: Symbol = Symbol(25);\npub const INTERNED_OP_IMPL_LTEQ: Symbol = Symbol(26);\npub const INTERNED_OP_IMPL_GTEQ: Symbol = Symbol(27);\npub const INTERNED_OP_IMPL_NEG: Symbol = Symbol(28);\npub const INTERNED_OP_PRETTYPRINT: Symbol = Symbol(29);\n\npub const INTERNED_ATTR_BACKTRACE: Symbol = Symbol(30);\npub const INTERNED_ATTR_IMPL: Symbol = Symbol(31);\npub const INTERNED_ATTR_NEXT: Symbol = Symbol(32);\npub const INTERNED_ATTR_MSG: Symbol = Symbol(33);\npub const INTERNED_ATTR_ARGC_MISMATCH: Symbol = Symbol(34);\npub const INTERNED_ATTR_STDOUT: Symbol = Symbol(35);\npub const INTERNED_ATTR_STDERR: Symbol = Symbol(36);\npub const INTERNED_ATTR_EXPECTED: Symbol = Symbol(37);\npub const INTERNED_ATTR_ACTUAL: Symbol = Symbol(38);\n\npub const INTERNED_CASE_VARARGS: Symbol = Symbol(39);\npub const INTERNED_CASE_BOUNDED: Symbol = Symbol(40);\n\npub struct Interner {\n    map: FxHashMap<String, Symbol>,\n    strings: Vec<String>,\n}\n\n#[derive(Clone, Error, PartialEq, Eq, Debug)]\npub enum InternError {\n    #[error(\"too many symbols have been interned\")]\n    TooManySymbols,\n}\n\nimpl Default for Interner {\n    fn default() -> Self {\n        let mut this = Self {\n            map: FxHashMap::default(),\n            strings: Vec::new(),\n        };\n\n        // do not alter the order of these initial interned symbols\n        // without altering the corresponding constants above\n        assert!(this.intern(\"_op_impl_call\").unwrap() == INTERNED_OP_IMPL_CALL);\n        assert!(this.intern(\"_op_impl_equals\").unwrap() == INTERNED_OP_IMPL_EQUALS);\n        assert!(this.intern(\"_op_impl_read_index\").unwrap() == INTERNED_OP_IMPL_READ_INDEX);\n        assert!(this.intern(\"_op_impl_write_index\").unwrap() == INTERNED_OP_IMPL_WRITE_INDEX);\n        assert!(this.intern(\"_op_impl_add\").unwrap() == INTERNED_OP_IMPL_ADD);\n        assert!(this.intern(\"_op_impl_radd\").unwrap() == INTERNED_OP_IMPL_RADD);\n        assert!(this.intern(\"_op_impl_sub\").unwrap() == INTERNED_OP_IMPL_SUB);\n        assert!(this.intern(\"_op_impl_rsub\").unwrap() == INTERNED_OP_IMPL_RSUB);\n        assert!(this.intern(\"_op_impl_mul\").unwrap() == INTERNED_OP_IMPL_MUL);\n        assert!(this.intern(\"_op_impl_rmul\").unwrap() == INTERNED_OP_IMPL_RMUL);\n        assert!(this.intern(\"_op_impl_div\").unwrap() == INTERNED_OP_IMPL_DIV);\n        assert!(this.intern(\"_op_impl_rdiv\").unwrap() == INTERNED_OP_IMPL_RDIV);\n        assert!(this.intern(\"_op_impl_rem\").unwrap() == INTERNED_OP_IMPL_REM);\n        assert!(this.intern(\"_op_impl_rrem\").unwrap() == INTERNED_OP_IMPL_RREM);\n        assert!(this.intern(\"_op_impl_lshift\").unwrap() == INTERNED_OP_IMPL_LSHIFT);\n        assert!(this.intern(\"_op_impl_rlshift\").unwrap() == INTERNED_OP_IMPL_RLSHIFT);\n        assert!(this.intern(\"_op_impl_rshift\").unwrap() == INTERNED_OP_IMPL_RSHIFT);\n        assert!(this.intern(\"_op_impl_rrshift\").unwrap() == INTERNED_OP_IMPL_RRSHIFT);\n        assert!(this.intern(\"_op_impl_bwand\").unwrap() == INTERNED_OP_IMPL_BWAND);\n        assert!(this.intern(\"_op_impl_rbwand\").unwrap() == INTERNED_OP_IMPL_RBWAND);\n        assert!(this.intern(\"_op_impl_bwor\").unwrap() == INTERNED_OP_IMPL_BWOR);\n        assert!(this.intern(\"_op_impl_rbwor\").unwrap() == INTERNED_OP_IMPL_RBWOR);\n        assert!(this.intern(\"_op_impl_xor\").unwrap() == INTERNED_OP_IMPL_XOR);\n        assert!(this.intern(\"_op_impl_rxor\").unwrap() == INTERNED_OP_IMPL_RXOR);\n        assert!(this.intern(\"_op_impl_lt\").unwrap() == INTERNED_OP_IMPL_LT);\n        assert!(this.intern(\"_op_impl_gt\").unwrap() == INTERNED_OP_IMPL_GT);\n        assert!(this.intern(\"_op_impl_lteq\").unwrap() == INTERNED_OP_IMPL_LTEQ);\n        assert!(this.intern(\"_op_impl_gteq\").unwrap() == INTERNED_OP_IMPL_GTEQ);\n        assert!(this.intern(\"_op_impl_neg\").unwrap() == INTERNED_OP_IMPL_NEG);\n        assert!(this.intern(\"prettyprint\").unwrap() == INTERNED_OP_PRETTYPRINT);\n\n        assert!(this.intern(\"backtrace\").unwrap() == INTERNED_ATTR_BACKTRACE);\n        assert!(this.intern(\"__impl\").unwrap() == INTERNED_ATTR_IMPL);\n        assert!(this.intern(\"next\").unwrap() == INTERNED_ATTR_NEXT);\n        assert!(this.intern(\"msg\").unwrap() == INTERNED_ATTR_MSG);\n        assert!(this.intern(\"ArgcMismatch\").unwrap() == INTERNED_ATTR_ARGC_MISMATCH);\n        assert!(this.intern(\"stdout\").unwrap() == INTERNED_ATTR_STDOUT);\n        assert!(this.intern(\"stderr\").unwrap() == INTERNED_ATTR_STDERR);\n        assert!(this.intern(\"expected\").unwrap() == INTERNED_ATTR_EXPECTED);\n        assert!(this.intern(\"actual\").unwrap() == INTERNED_ATTR_ACTUAL);\n\n        assert!(this.intern(\"Varargs\").unwrap() == INTERNED_CASE_VARARGS);\n        assert!(this.intern(\"Bounded\").unwrap() == INTERNED_CASE_BOUNDED);\n\n        this\n    }\n}\n\nimpl Interner {\n    pub fn intern(&mut self, s: &str) -> Result<Symbol, InternError> {\n        if let Some(&sym) = self.map.get(s) {\n            return Ok(sym);\n        }\n\n        let id = self.strings.len();\n        if id >= u32::MAX as usize {\n            return Err(InternError::TooManySymbols);\n        }\n\n        let s = s.to_string();\n\n        let sym = Symbol(id as u32);\n        self.strings.push(s.clone());\n        self.map.insert(s, sym);\n        Ok(sym)\n    }\n\n    pub fn lookup(&self, s: &str) -> Option<Symbol> {\n        self.map.get(s).copied()\n    }\n\n    pub fn resolve(&self, sym: Symbol) -> Option<&str> {\n        self.strings.get(sym.0 as usize).map(|s| s.as_str())\n    }\n}\n"
  },
  {
    "path": "vm-lib/src/test.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse aria_compiler::compile_from_source;\nuse aria_parser::ast::SourceBuffer;\n\nuse crate::{\n    HaxbyEvalResult,\n    builtins::runtime_error::RUNTIME_ERR_CASE_UNEXPECTED_TYPE_IDX,\n    error::vm_error::VmErrorReason,\n    haxby_eval,\n    vm::{ExecutionResult, VmOptions},\n};\n\nfn exec_code(src: &'static str) -> ExecutionResult<HaxbyEvalResult> {\n    exec_code_with_vm_options(src, Default::default())\n}\n\nfn exec_code_with_vm_options(\n    src: &'static str,\n    vm_opts: VmOptions,\n) -> ExecutionResult<HaxbyEvalResult> {\n    let sb = SourceBuffer::stdin(src);\n    let module = compile_from_source(&sb, &Default::default()).expect(\"module did not compile\");\n    haxby_eval(module, vm_opts)\n}\n\n#[test]\nfn test_assert_can_pass() {\n    let input = r##\"\nfunc main() {\n    val x = 1;\n    assert x == 1;\n}\n\"##;\n\n    assert!(exec_code(input).is_ok());\n}\n\n#[test]\nfn test_assert_can_fail() {\n    let input = r##\"\nfunc main() {\n    val x = 1;\n    assert x == 2;\n}\n\"##;\n\n    assert!(\n        exec_code(input)\n            .is_err_and(|err| err.reason == VmErrorReason::AssertFailed(\"x == 2\".to_owned()))\n    );\n}\n\n#[test]\nfn test_toplevel_assert_can_fail() {\n    let input = r##\"\nval x = 1;\nassert x == 2;\n\"##;\n\n    assert!(\n        exec_code(input)\n            .is_err_and(|err| err.reason == VmErrorReason::AssertFailed(\"x == 2\".to_owned()))\n    );\n}\n\n#[test]\nfn test_circular_import_detected() {\n    let input = r##\"\nimport circular.zero;\n\nfunc main() {\n    assert false;\n}\n\"##;\n\n    assert!(\n        exec_code(input).is_err_and(\n            |err| err.reason == VmErrorReason::CircularImport(\"circular.zero\".to_owned())\n        )\n    );\n}\n\n#[test]\nfn test_module_val_typecheck_fails() {\n    let input = r##\"\nval x: Int = 1;\n\nfunc main() {\n    x = \"false\";\n    assert false;\n}\n\"##;\n\n    let result = exec_code(input);\n    match result {\n        Ok(result) => match result.exit {\n            crate::vm::RunloopExit::Ok(_) => {\n                panic!(\"expected typecheck to fail\");\n            }\n            crate::vm::RunloopExit::Exception(e) => {\n                let enum_value = e\n                    .value\n                    .as_enum_value()\n                    .expect(\"exception should be an enum value\");\n                assert!(enum_value.get_case_index() == RUNTIME_ERR_CASE_UNEXPECTED_TYPE_IDX);\n            }\n        },\n        Err(_) => {\n            panic!(\"expected exception to be thrown\");\n        }\n    }\n}\n\n#[test]\nfn test_err_in_op_is_caught() {\n    let input = r##\"\nstruct Foo {\n    operator + (rhs) {\n        assert false;\n    }\n}\n\nfunc main() {\n    return alloc(Foo) + 1;\n}\n\"##;\n\n    assert!(\n        exec_code(input)\n            .is_err_and(|err| err.reason == VmErrorReason::AssertFailed(\"false\".to_owned()))\n    );\n}\n\n#[test]\nfn test_err_in_rop_is_caught() {\n    let input = r##\"\nstruct Foo {\n    reverse operator + (lhs) {\n        assert false;\n    }\n}\n\nfunc main() {\n    return 1 + alloc(Foo);\n}\n\"##;\n\n    assert!(\n        exec_code(input)\n            .is_err_and(|err| err.reason == VmErrorReason::AssertFailed(\"false\".to_owned()))\n    );\n}\n\n#[test]\nfn test_uncaught_exception_bubbles_up() {\n    let input = r##\"\nfunc main() {\n    throw 1;\n}\n\"##;\n\n    match exec_code(input).expect(\"ok result expected\").exit {\n        crate::vm::RunloopExit::Ok(_) => {\n            panic!(\"expected exception to be thrown\");\n        }\n        crate::vm::RunloopExit::Exception(e) => {\n            assert_eq!(\n                1,\n                *e.value\n                    .as_integer()\n                    .expect(\"integer value thrown\")\n                    .raw_value()\n            )\n        }\n    }\n}\n\n#[test]\nfn test_cmdline_arguments() {\n    let input = r##\"\nfunc main() {\n    val args = cmdline_arguments();\n    assert args.len() == 2;\n    assert args[0] == \"foo\";\n    assert args[1] == \"bar\";\n}\n\"##;\n\n    assert!(\n        exec_code_with_vm_options(\n            input,\n            VmOptions {\n                vm_args: vec![\"foo\".to_owned(), \"bar\".to_owned()],\n                ..Default::default()\n            }\n        )\n        .is_ok()\n    );\n}\n\n#[test]\nfn test_force_unwrap_asserts() {\n    let input = r##\"\nfunc main() {\n    val x = Result::Err(\"fail\");\n    assert x! == 3;\n}\n\"##;\n\n    assert!(exec_code(input).is_err_and(\n        |err| err.reason == VmErrorReason::AssertFailed(\"force unwrap failed\".to_owned())\n    ));\n}\n\n#[test]\nfn test_cmdline_args_list() {\n    let input = r##\"\nfunc main(args) {\n    assert args.len() == 2;\n    assert args[0] == \"arg1\";\n    assert args[1] == \"arg2\";\n}\n\"##;\n\n    let vm_opts = VmOptions {\n        vm_args: vec![\"arg1\".to_owned(), \"arg2\".to_owned()],\n        ..Default::default()\n    };\n    assert!(exec_code_with_vm_options(input, vm_opts).is_ok());\n}\n\n#[test]\nfn test_cmdline_args_va() {\n    let input = r##\"\nfunc main(...) {\n    assert varargs.len() == 2;\n    assert varargs[0] == \"arg1\";\n    assert varargs[1] == \"arg2\";\n}\n\"##;\n\n    let vm_opts = VmOptions {\n        vm_args: vec![\"arg1\".to_owned(), \"arg2\".to_owned()],\n        ..Default::default()\n    };\n    assert!(exec_code_with_vm_options(input, vm_opts).is_ok());\n}\n\n#[test]\nfn test_cmdline_args_mismatch() {\n    let input = r##\"\nfunc main(x,y,z,...) {\n    val x = Result::Err(\"fail\");\n    assert x! == 3;\n}\n\"##;\n\n    let vm_opts = VmOptions {\n        vm_args: vec![\"arg1\".to_owned(), \"arg2\".to_owned()],\n        ..Default::default()\n    };\n\n    assert!(\n        exec_code_with_vm_options(input, vm_opts)\n            .is_err_and(|err| err.reason == VmErrorReason::InvalidMainSignature)\n    );\n}\n"
  },
  {
    "path": "vm-lib/src/vm.rs",
    "content": "// SPDX-License-Identifier: Apache-2.0\nuse std::{\n    cell::RefCell,\n    collections::HashMap,\n    path::{Path, PathBuf},\n    rc::Rc,\n};\n\nuse aria_compiler::{compile_from_source, module::CompiledModule};\nuse aria_parser::ast::SourceBuffer;\nuse haxby_opcodes::{\n    BuiltinTypeId, OPCODE_BIND_CASE, OPCODE_ENUM_CHECK_IS_CASE, OPCODE_NEW_ENUM_VAL,\n    OPCODE_READ_ATTRIBUTE, OPCODE_WRITE_ATTRIBUTE, Opcode, enum_case_attribs::CASE_HAS_PAYLOAD,\n};\nuse std::sync::OnceLock;\n\nuse crate::{\n    builtins::VmGlobals,\n    console::{Console, StdConsole},\n    error::{\n        dylib_load::{LoadResult, LoadStatus},\n        exception::VmException,\n        vm_error::{SymbolKind, VmError, VmErrorReason},\n    },\n    frame::Frame,\n    opcodes::sidecar::{\n        EnumCheckIsCaseSidecar, NewEnumValSidecar, OpcodeSidecar, ReadAttributeSidecar,\n        SidecarCell, SidecarSlice,\n    },\n    runtime_module::RuntimeModule,\n    runtime_value::{\n        RuntimeValue,\n        enumeration::{Enum, EnumCase},\n        function::Function,\n        isa::IsaCheckable,\n        kind::RuntimeValueType,\n        list::List,\n        mixin::Mixin,\n        object::Object,\n        structure::Struct,\n    },\n    stack::Stack,\n};\n\npub type ConsoleHandle = Rc<RefCell<dyn Console>>;\n\n#[derive(Clone)]\npub struct VmOptions {\n    #[cfg(debug_assertions)]\n    pub tracing: bool,\n    #[cfg(debug_assertions)]\n    pub dump_stack: bool,\n    pub vm_args: Vec<String>,\n    pub console: ConsoleHandle,\n}\n\nimpl Default for VmOptions {\n    fn default() -> Self {\n        Self {\n            #[cfg(debug_assertions)]\n            tracing: Default::default(),\n            #[cfg(debug_assertions)]\n            dump_stack: Default::default(),\n            vm_args: Default::default(),\n            console: Rc::new(RefCell::new(StdConsole {})),\n        }\n    }\n}\n\npub struct VirtualMachine {\n    pub modules: HashMap<String, RuntimeModule>,\n    pub options: VmOptions,\n    pub globals: VmGlobals,\n    pub import_stack: Stack<String>,\n    pub imported_modules: HashMap<String, ModuleLoadInfo>,\n    pub loaded_dylibs: HashMap<String, libloading::Library>,\n    frame_pool: Vec<Frame>,\n}\n\nimpl VirtualMachine {\n    pub fn console(&self) -> &ConsoleHandle {\n        &self.options.console\n    }\n\n    pub(crate) fn acquire_frame(&mut self, f: &Function) -> Frame {\n        let mut frame = self.frame_pool.pop().unwrap_or_default();\n        frame.reset_for_function(f);\n        frame\n    }\n\n    pub(crate) fn release_frame(&mut self, frame: Frame) {\n        self.frame_pool.push(frame.reset_for_pool());\n    }\n\n    fn load_version_into_globals(mut self) -> Self {\n        let aria_version = env!(\"CARGO_PKG_VERSION\");\n        assert!(!aria_version.is_empty());\n        self.globals\n            .insert(\"ARIA_VERSION\", RuntimeValue::String(aria_version.into()));\n        self\n    }\n}\n\nimpl Default for VirtualMachine {\n    fn default() -> Self {\n        let options = Default::default();\n        VirtualMachine::with_options(options)\n    }\n}\n\nimpl VirtualMachine {\n    pub fn with_options(options: VmOptions) -> Self {\n        Self {\n            modules: Default::default(),\n            options,\n            globals: Default::default(),\n            import_stack: Default::default(),\n            imported_modules: Default::default(),\n            loaded_dylibs: Default::default(),\n            frame_pool: Default::default(),\n        }\n        .load_version_into_globals()\n    }\n}\n\nmacro_rules! build_vm_error {\n    ($reason: expr, $next: expr, $frame: expr, $idx: expr) => {{\n        let lt = if let Some(lt) = $frame.get_line_table() {\n            lt.get(*$idx as u16)\n        } else {\n            None\n        };\n        Err($crate::error::vm_error::VmError {\n            reason: $reason,\n            opcode: Some($next),\n            loc: lt,\n            backtrace: Default::default(),\n        })\n    }};\n}\n\nmacro_rules! pop_or_err {\n    ($next: expr, $frame: expr, $idx: expr) => {\n        if let Some(val) = $frame.stack.try_pop() {\n            val\n        } else {\n            return build_vm_error!(VmErrorReason::EmptyStack, $next, $frame, $idx);\n        }\n    };\n}\n\npub type ExecutionResult<T = (), U = VmError> = Result<T, U>;\n\npub struct ModuleLoadInfo {\n    pub module: RuntimeModule,\n}\n\npub enum RunloopExit<T = ()> {\n    Ok(T),\n    Exception(crate::error::exception::VmException),\n}\n\nimpl RunloopExit {\n    pub fn throw_object(value: RuntimeValue) -> Self {\n        Self::Exception(VmException {\n            value,\n            backtrace: Default::default(),\n        })\n    }\n\n    pub fn throw_struct(\n        struk: &Struct,\n        values: &[(crate::symbol::Symbol, RuntimeValue)],\n        builtins: &mut VmGlobals,\n    ) -> Self {\n        let object = RuntimeValue::Object(Object::new(struk));\n        for value in values {\n            let _ = object.write_attribute(value.0, value.1.clone(), builtins);\n        }\n\n        Self::throw_object(object)\n    }\n}\n\nenum OpcodeRunExit {\n    Continue,\n    Return,\n    Exception(VmException),\n}\n\nmacro_rules! binop_eval {\n    ( ($op_expr: expr), $next: expr, $frame: expr, $op_idx: expr) => {\n        match $op_expr {\n            crate::runtime_value::OperatorEvalOutcome::Ok(val) => $frame.stack.push(val),\n            crate::runtime_value::OperatorEvalOutcome::Exception(e) => {\n                return Ok(OpcodeRunExit::Exception(e));\n            }\n            crate::runtime_value::OperatorEvalOutcome::Error(err) => {\n                if err.loc.is_some() {\n                    return Err(err);\n                } else {\n                    return build_vm_error!(err.reason, $next, $frame, $op_idx);\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! unaryop_eval {\n    ( ($op_expr: expr), $next: expr, $frame: expr, $op_idx: expr) => {\n        match $op_expr {\n            crate::runtime_value::OperatorEvalOutcome::Ok(val) => $frame.stack.push(val),\n            crate::runtime_value::OperatorEvalOutcome::Exception(e) => {\n                return Ok(OpcodeRunExit::Exception(e));\n            }\n            crate::runtime_value::OperatorEvalOutcome::Error(err) => {\n                if err.loc.is_some() {\n                    return Err(err);\n                } else {\n                    return build_vm_error!(err.reason, $next, $frame, $op_idx);\n                }\n            }\n        }\n    };\n}\n\nfn get_lib_path(lib_name: &str) -> PathBuf {\n    let exe_path = std::env::current_exe().expect(\"failed to get current exe path\");\n    let exe_dir = exe_path.parent().expect(\"failed to get exe directory\");\n    let lib_name = libloading::library_filename(lib_name);\n    exe_dir.join(lib_name)\n}\n\nfn unique_insert<T>(vec: &mut Vec<T>, item: T) -> &Vec<T>\nwhere\n    T: PartialEq,\n{\n    if !vec.contains(&item) {\n        vec.push(item);\n    }\n    vec\n}\n\nimpl VirtualMachine {\n    fn get_system_import_paths() -> Vec<PathBuf> {\n        if let Ok(env_var) = std::env::var(\"ARIA_LIB_DIR\") {\n            let mut paths = Vec::new();\n            for candidate_dir in std::env::split_paths(env_var.as_str()) {\n                if candidate_dir.exists() && candidate_dir.is_dir() {\n                    paths.push(candidate_dir);\n                }\n            }\n\n            if !paths.is_empty() {\n                return paths;\n            }\n        }\n\n        if let Ok(exe_path) = std::env::current_exe()\n            && let Some(exe_dir) = exe_path.parent()\n        {\n            let lib_aria_path = exe_dir.join(\"lib\");\n            if lib_aria_path.join(\"aria\").is_dir() {\n                return vec![lib_aria_path];\n            }\n\n            if let Some(exe_parent_dir) = exe_dir.parent() {\n                let lib_aria_path = exe_parent_dir.join(\"lib\");\n                if lib_aria_path.join(\"aria\").is_dir() {\n                    return vec![lib_aria_path];\n                }\n            }\n        }\n\n        let version = env!(\"CARGO_PKG_VERSION\");\n\n        #[cfg(target_os = \"linux\")]\n        {\n            let system_lib_path = PathBuf::from(format!(\"/usr/local/aria{}/lib\", version));\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n\n            let system_lib_path = PathBuf::from(\"/usr/local/aria/lib\");\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n\n            let system_lib_path = PathBuf::from(format!(\"/usr/lib/aria{}\", version));\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n\n            let system_lib_path = PathBuf::from(\"/usr/lib/aria\");\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n        }\n\n        #[cfg(target_os = \"macos\")]\n        {\n            let system_lib_path = PathBuf::from(format!(\"/opt/homebrew/opt/aria{}/lib\", version));\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n\n            let system_lib_path = PathBuf::from(\"/opt/homebrew/opt/aria/lib\");\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n\n            let version = env!(\"CARGO_PKG_VERSION\");\n            let system_lib_path = PathBuf::from(format!(\"/usr/local/opt/aria{}/lib\", version));\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n\n            let system_lib_path = PathBuf::from(\"/usr/local/opt/aria/lib\");\n            if system_lib_path.join(\"aria\").is_dir() {\n                return vec![system_lib_path];\n            }\n        }\n\n        Vec::new()\n    }\n\n    pub fn get_aria_library_paths() -> &'static Vec<PathBuf> {\n        static ARIA_LIBRARY_PATHS: OnceLock<Vec<PathBuf>> = OnceLock::new();\n\n        ARIA_LIBRARY_PATHS.get_or_init(|| {\n            let mut paths = Self::get_system_import_paths();\n\n            if let Ok(env_var) = std::env::var(\"ARIA_LIB_DIR_EXTRA\") {\n                for candidate_dir in std::env::split_paths(env_var.as_str()) {\n                    if candidate_dir.exists() && candidate_dir.is_dir() {\n                        paths.push(candidate_dir);\n                    }\n                }\n            }\n\n            let mut ret_paths = vec![];\n            for path in paths {\n                if let Ok(can) = std::fs::canonicalize(path) {\n                    unique_insert(&mut ret_paths, can);\n                }\n            }\n\n            ret_paths\n        })\n    }\n\n    fn try_get_import_path_from_name(\n        aria_lib_dir: impl AsRef<Path>,\n        ipath: &str,\n    ) -> Option<PathBuf> {\n        let mut module_path = aria_lib_dir.as_ref().to_path_buf();\n        module_path.push(ipath);\n        if module_path.exists() {\n            Some(module_path)\n        } else {\n            None\n        }\n    }\n\n    fn resolve_import_path_to_path(\n        ipath: &str,\n        widget_root_path: Option<&PathBuf>,\n    ) -> Result<PathBuf, VmErrorReason> {\n        if let Some(ipath) = ipath.strip_prefix(\"widget.\") {\n            return if let Some(widget_root_path) = widget_root_path {\n                let ipath = format!(\"{}.aria\", ipath.replace(\".\", \"/\"));\n                Self::try_get_import_path_from_name(widget_root_path, &ipath).ok_or_else(|| {\n                    VmErrorReason::ImportNotAvailable(\n                        ipath.to_owned(),\n                        \"import not found in widget\".to_owned(),\n                    )\n                })\n            } else {\n                Err(VmErrorReason::ImportNotAvailable(\n                    ipath.to_owned(),\n                    \"tried to import from widget without a widget.json\".to_owned(),\n                ))\n            };\n        }\n\n        let ipath = format!(\"{}.aria\", ipath.replace(\".\", \"/\"));\n\n        let aria_lib_dirs = VirtualMachine::get_aria_library_paths();\n        for aria_lib_dir in aria_lib_dirs {\n            if let Some(path) = Self::try_get_import_path_from_name(aria_lib_dir, &ipath) {\n                return Ok(path);\n            }\n        }\n\n        Err(VmErrorReason::ImportNotAvailable(\n            ipath.to_owned(),\n            \"no such path\".to_owned(),\n        ))\n    }\n\n    fn create_import_model_from_path(\n        module: &RuntimeModule,\n        builtins: &mut VmGlobals,\n        ipath: &str,\n        leaf: RuntimeValue,\n    ) -> Result<RuntimeValue, VmErrorReason> {\n        let components = ipath.split(\".\").collect::<Vec<_>>();\n        if components.len() == 1 {\n            let cmp_last = components[0];\n            module.store_named_value(cmp_last, leaf.clone());\n            return Ok(leaf);\n        }\n\n        let cmp0 = components[0];\n        let root = if let Some(cmp0_obj) = module.load_named_value(cmp0)\n            && cmp0_obj.is_enum()\n        {\n            cmp0_obj\n        } else {\n            let cmp0_struct = Enum::new(cmp0);\n            let cmp0_val = RuntimeValue::Type(RuntimeValueType::Enum(cmp0_struct.clone()));\n            module.store_named_value(cmp0, cmp0_val);\n            RuntimeValue::Type(RuntimeValueType::Enum(cmp0_struct))\n        };\n\n        let mut current_struct = root.clone();\n\n        fn get_or_create_empty_enum(\n            current_struct: &RuntimeValue,\n            name: &str,\n            builtins: &mut VmGlobals,\n        ) -> Result<RuntimeValue, VmErrorReason> {\n            let sym = builtins.intern_symbol(name)?;\n            if let Ok(existing_val) = current_struct.read_attribute(sym, builtins)\n                && existing_val.is_enum()\n            {\n                Ok(existing_val)\n            } else {\n                let new_val = RuntimeValue::Type(RuntimeValueType::Enum(Enum::new(name)));\n                let _ = current_struct.write_attribute(sym, new_val.clone(), builtins);\n                Ok(new_val)\n            }\n        }\n\n        for cmp in components.iter().take(components.len() - 1).skip(1) {\n            current_struct = get_or_create_empty_enum(&current_struct, cmp, builtins)?\n        }\n\n        let cmp_last = components.last().unwrap();\n        let sym = builtins.intern_symbol(cmp_last)?;\n        let _ = current_struct.write_attribute(sym, leaf.clone(), builtins);\n\n        Ok(root)\n    }\n\n    pub fn load_into_module(\n        &mut self,\n        name: &str,\n        r_mod: RuntimeModule,\n    ) -> ExecutionResult<RunloopExit<ModuleLoadInfo>> {\n        if !name.is_empty() {\n            self.modules.insert(name.to_owned(), r_mod.clone());\n        }\n\n        let entry_co = r_mod.load_entry_code_object();\n        let entry_f = Function::from_code_object(entry_co, &r_mod);\n        let mut entry_frame: Frame = Default::default();\n\n        let entry_result = entry_f.eval(0, &mut entry_frame, self, &Default::default(), true);\n        match entry_result {\n            Ok(ok) => match ok {\n                crate::runtime_value::CallResult::Exception(e) => Ok(RunloopExit::Exception(e)),\n                _ => Ok(RunloopExit::Ok(ModuleLoadInfo { module: r_mod })),\n            },\n            Err(err) => Err(err),\n        }\n    }\n\n    pub fn load_module(\n        &mut self,\n        name: &str,\n        entry_cm: CompiledModule,\n    ) -> ExecutionResult<RunloopExit<ModuleLoadInfo>> {\n        let r_mod = RuntimeModule::new(self, entry_cm)?;\n        self.load_into_module(name, r_mod)\n    }\n\n    pub fn get_module_by_name(&self, name: &str) -> Option<RuntimeModule> {\n        self.modules.get(name).cloned()\n    }\n\n    pub(crate) fn find_imported_module(&self, name: &str) -> Option<RuntimeModule> {\n        self.imported_modules\n            .get(name)\n            .map(|mli| mli.module.clone())\n    }\n\n    pub fn inject_imported_module(&mut self, name: &str, module: RuntimeModule) {\n        self.imported_modules\n            .insert(name.to_owned(), ModuleLoadInfo { module });\n    }\n\n    pub fn execute_module(&mut self, m: &RuntimeModule) -> ExecutionResult<RunloopExit> {\n        let main_f = match m.load_named_value(\"main\") {\n            Some(RuntimeValue::Function(f)) => f,\n            _ => return Ok(RunloopExit::Ok(())),\n        };\n\n        let mut main_frame = Frame::default();\n\n        let main_arity = main_f.arity();\n        let req = main_arity.required;\n        let opt = main_arity.optional;\n        let va = main_f.varargs();\n        let main_argc = if req == 0 && opt == 0 && !va {\n            0\n        } else if req == 1 && opt == 0 && !va {\n            let cmdline_args = RuntimeValue::List(List::from(\n                &self\n                    .options\n                    .vm_args\n                    .iter()\n                    .map(|arg| RuntimeValue::String(arg.as_str().into()))\n                    .collect::<Vec<_>>(),\n            ));\n            main_frame.stack.push(cmdline_args);\n            1\n        } else if req == 0 && opt == 0 && va {\n            self.options\n                .vm_args\n                .iter()\n                .rev()\n                .map(|arg| RuntimeValue::String(arg.as_str().into()))\n                .for_each(|arg| main_frame.stack.push(arg));\n            self.options.vm_args.len() as u8\n        } else {\n            return Err(VmErrorReason::InvalidMainSignature.into());\n        };\n\n        match main_f.eval(main_argc, &mut main_frame, self, &Default::default(), true)? {\n            crate::runtime_value::CallResult::Ok(_) => Ok(RunloopExit::Ok(())),\n            crate::runtime_value::CallResult::Exception(e) => Ok(RunloopExit::Exception(e)),\n        }\n    }\n\n    fn read_named_symbol(\n        &self,\n        module: &RuntimeModule,\n        name: &str,\n    ) -> Result<RuntimeValue, VmErrorReason> {\n        match module.load_named_value(name) {\n            Some(nv) => Ok(nv),\n            _ => match self.globals.load_named_value(name) {\n                Some(nv) => Ok(nv),\n                _ => Err(VmErrorReason::NoSuchIdentifier(name.to_owned())),\n            },\n        }\n    }\n\n    pub(crate) fn eval_bytecode_in_frame(\n        &mut self,\n        module: &RuntimeModule,\n        bc: &[Opcode],\n        sidecar: &SidecarSlice,\n        target_frame: &mut Frame,\n    ) -> ExecutionResult<RunloopExit> {\n        self.runloop(bc, sidecar, module, target_frame)\n    }\n\n    fn run_opcode(\n        &mut self,\n        next: Opcode,\n        next_sidecar: &SidecarCell,\n        op_idx: &mut usize,\n        this_module: &RuntimeModule,\n        frame: &mut Frame,\n    ) -> ExecutionResult<OpcodeRunExit, VmError> {\n        match next {\n            Opcode::Nop => {}\n            Opcode::Push(n) => match this_module.load_indexed_const(n) {\n                Some(rv) => {\n                    frame.stack.push(rv.clone());\n                }\n                None => {\n                    return build_vm_error!(\n                        VmErrorReason::NoSuchModuleConstant(n),\n                        next,\n                        frame,\n                        op_idx\n                    );\n                }\n            },\n            Opcode::Push0 => frame.stack.push(RuntimeValue::Integer(0.into())),\n            Opcode::Push1 => frame.stack.push(RuntimeValue::Integer(1.into())),\n            Opcode::PushTrue => frame.stack.push(RuntimeValue::Boolean(true.into())),\n            Opcode::PushFalse => frame.stack.push(RuntimeValue::Boolean(false.into())),\n            Opcode::PushBuiltinTy(n) => frame\n                .stack\n                .push(RuntimeValue::Type(self.globals.get_builtin_type_by_id(n))),\n            Opcode::PushRuntimeValue(n) => match n {\n                haxby_opcodes::BuiltinValueId::ThisModule => {\n                    frame.stack.push(RuntimeValue::Module(this_module.clone()))\n                }\n            },\n            Opcode::Pop => {\n                pop_or_err!(next, frame, op_idx);\n            }\n            Opcode::Dup => {\n                if let Some(val) = frame.stack.peek() {\n                    let val = val.clone();\n                    frame.stack.push(val);\n                }\n            }\n            Opcode::Swap => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                frame.stack.push(x);\n                frame.stack.push(y);\n            }\n            Opcode::Copy(n) => {\n                let val = frame.stack.peek_at_offset(n as usize);\n                if let Some(val) = val {\n                    let val = val.clone();\n                    frame.stack.push(val);\n                }\n            }\n            Opcode::Add => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Integer(b + a));\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(b + &a.to_fp()));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(&b.to_fp() + a));\n                } else if let (RuntimeValue::String(a), RuntimeValue::String(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::String(b + a));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(b + a))\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::add(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::Sub => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Integer(b - a));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(b - a))\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(b - &a.to_fp()));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(&b.to_fp() - a));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::sub(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::Mul => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Integer(b * a));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(b * a))\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(b * &a.to_fp()));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Float(&b.to_fp() * a));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::mul(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::Div => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    if *a.raw_value() == 0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Integer(b / a));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    if *a.raw_value() == 0.0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Float(b / a))\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    if *a.raw_value() == 0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Float(b / &a.to_fp()));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    if *a.raw_value() == 0.0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Float(&b.to_fp() / a));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::div(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::Rem => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    if *a.raw_value() == 0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Integer(b % a));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    if *a.raw_value() == 0.0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Float(b % a))\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    if *a.raw_value() == 0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Float(b % &a.to_fp()))\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    if *a.raw_value() == 0.0 {\n                        return build_vm_error!(VmErrorReason::DivisionByZero, next, frame, op_idx);\n                    }\n                    frame.stack.push(RuntimeValue::Float(&b.to_fp() % a))\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::rem(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::Neg => {\n                let n = pop_or_err!(next, frame, op_idx);\n                if let RuntimeValue::Integer(i) = &n {\n                    frame.stack.push(RuntimeValue::Integer(-i));\n                } else if let RuntimeValue::Float(i) = &n {\n                    frame.stack.push(RuntimeValue::Float(-i));\n                } else {\n                    unaryop_eval!((RuntimeValue::neg(&n, frame, self)), next, frame, op_idx)\n                }\n            }\n            Opcode::ShiftLeft => {\n                let by = pop_or_err!(next, frame, op_idx);\n                let n = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(n), RuntimeValue::Integer(by)) = (&n, &by) {\n                    frame.stack.push(RuntimeValue::Integer(n << by));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::leftshift(&n, &by, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::ShiftRight => {\n                let by = pop_or_err!(next, frame, op_idx);\n                let n = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(n), RuntimeValue::Integer(by)) = (&n, &by) {\n                    frame.stack.push(RuntimeValue::Integer(n >> by));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::rightshift(&n, &by, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::Not => {\n                let b = pop_or_err!(next, frame, op_idx);\n                if let RuntimeValue::Boolean(b) = b {\n                    frame.stack.push(RuntimeValue::Boolean(!b));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::Equal => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                let eq_result =\n                    RuntimeValue::Boolean(Into::into(RuntimeValue::equals(&y, &x, frame, self)));\n                frame.stack.push(eq_result);\n            }\n            Opcode::LessThan => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b < a)));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b < a)));\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(*b < a.to_fp())));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(b.to_fp() < *a)));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::less_than(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::LessThanEqual => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b <= a)));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b <= a)));\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(*b <= a.to_fp())));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(b.to_fp() <= *a)));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::less_than_equal(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::GreaterThan => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b > a)));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b > a)));\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(*b > a.to_fp())));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(b.to_fp() > *a)));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::greater_than(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::GreaterThanEqual => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b >= a)));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(Into::into(b >= a)));\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Float(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(*b >= a.to_fp())));\n                } else if let (RuntimeValue::Float(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Boolean(Into::into(b.to_fp() >= *a)));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::greater_than_equal(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::ReadLocal(n) => {\n                let local = frame.locals[n as usize].val.clone();\n                frame.stack.push(local);\n            }\n            Opcode::ReadUplevel(n) => {\n                if let Some(f) = &frame.func {\n                    if let Some(bcf) = f.imp.as_bytecode_function() {\n                        match bcf.read_uplevel(n) {\n                            Some(ulv) => {\n                                frame.stack.push(ulv);\n                            }\n                            _ => {\n                                return build_vm_error!(\n                                    VmErrorReason::UplevelOutOfBounds(n as usize),\n                                    next,\n                                    frame,\n                                    op_idx\n                                );\n                            }\n                        }\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::StoreUplevel(n) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                if let Some(f) = x.as_function() {\n                    if let Some(bcf) = f.imp.as_bytecode_function() {\n                        let local = frame.locals[n as usize].val.clone();\n                        bcf.store_uplevel(n, local);\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n                frame.stack.push(x);\n            }\n            Opcode::WriteLocal(n) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let local = &mut frame.locals[n as usize];\n                if !local.ty.isa_check(&x, &self.globals) {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                } else {\n                    local.val = x;\n                }\n            }\n            Opcode::TypedefLocal(n) => {\n                let t = pop_or_err!(next, frame, op_idx);\n                if let Ok(isa_check) = IsaCheckable::try_from(&t) {\n                    frame.locals[n as usize].ty = isa_check;\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::ReadNamed(n) => {\n                if let Some(ct) = this_module.load_indexed_const(n)\n                    && let Some(sv) = ct.as_string()\n                {\n                    frame\n                        .stack\n                        .push(self.read_named_symbol(this_module, sv.raw_value())?);\n                }\n            }\n            Opcode::WriteNamed(n) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                if let Some(ct) = this_module.load_indexed_const(n)\n                    && let Some(sv) = ct.as_string()\n                {\n                    let write_result =\n                        this_module.store_typechecked_named_value(sv.raw_value(), x, &self.globals);\n                    match write_result {\n                        Ok(_) => {}\n                        Err(e) => {\n                            return build_vm_error!(e, next, frame, op_idx);\n                        }\n                    }\n                }\n            }\n            Opcode::TypedefNamed(n) => {\n                let t = pop_or_err!(next, frame, op_idx);\n                if let Ok(t) = IsaCheckable::try_from(&t) {\n                    if let Some(ct) = this_module.load_indexed_const(n)\n                        && let Some(sv) = ct.as_string()\n                    {\n                        this_module.typedef_named_value(sv.raw_value(), t);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::ReadIndex(n) => {\n                let mut indices = Vec::<_>::with_capacity(n as usize);\n                for _ in 0..n {\n                    let idx = pop_or_err!(next, frame, op_idx);\n                    indices.push(idx);\n                }\n                indices.reverse();\n                let cnt = pop_or_err!(next, frame, op_idx);\n                match cnt.read_index(&indices, frame, self) {\n                    Ok(crate::runtime_value::CallResult::Ok(_)) => {}\n                    Ok(crate::runtime_value::CallResult::Exception(e)) => {\n                        return Ok(OpcodeRunExit::Exception(e));\n                    }\n                    Err(e) => {\n                        return if e.loc.is_none() {\n                            build_vm_error!(e.reason, next, frame, op_idx)\n                        } else {\n                            Err(e)\n                        };\n                    }\n                }\n            }\n            Opcode::WriteIndex(n) => {\n                let val = pop_or_err!(next, frame, op_idx);\n                let mut indices = Vec::<_>::with_capacity(n as usize);\n                for _ in 0..n {\n                    let idx = pop_or_err!(next, frame, op_idx);\n                    indices.push(idx);\n                }\n                indices.reverse();\n                let cnt = pop_or_err!(next, frame, op_idx);\n                match cnt.write_index(&indices, &val, frame, self) {\n                    Ok(crate::runtime_value::CallResult::Ok(_)) => {}\n                    Ok(crate::runtime_value::CallResult::Exception(e)) => {\n                        return Ok(OpcodeRunExit::Exception(e));\n                    }\n                    Err(e) => {\n                        return if e.loc.is_none() {\n                            build_vm_error!(e.reason, next, frame, op_idx)\n                        } else {\n                            Err(e)\n                        };\n                    }\n                }\n            }\n            Opcode::ReadAttribute(_) => {\n                return build_vm_error!(\n                    VmErrorReason::UnknownOpcode(OPCODE_READ_ATTRIBUTE),\n                    next,\n                    frame,\n                    op_idx\n                );\n            }\n            Opcode::WriteAttribute(_) => {\n                return build_vm_error!(\n                    VmErrorReason::UnknownOpcode(OPCODE_WRITE_ATTRIBUTE),\n                    next,\n                    frame,\n                    op_idx\n                );\n            }\n            Opcode::ReadAttributeSymbol(n) => {\n                let n = crate::symbol::Symbol(n);\n\n                let val_obj = pop_or_err!(next, frame, op_idx);\n\n                let current_sidecar = next_sidecar\n                    .get()\n                    .and_then(|sc| sc.as_read_attribute().copied());\n                let mut current_misses = current_sidecar\n                    .as_ref()\n                    .map(|sc| sc.misses)\n                    .unwrap_or_default();\n\n                if let Some(sc) = current_sidecar\n                    && current_misses < ReadAttributeSidecar::MAXIMUM_ALLOWED_MISSES\n                {\n                    if let Some(v) = val_obj.read_slot(&self.globals, sc.slot_id, sc.shape_id) {\n                        frame.stack.push(v);\n                        return Ok(OpcodeRunExit::Continue);\n                    } else {\n                        current_misses = current_misses\n                            .saturating_add(1)\n                            .clamp(0, ReadAttributeSidecar::MAXIMUM_ALLOWED_MISSES);\n                    }\n                }\n\n                if current_misses < ReadAttributeSidecar::MAXIMUM_ALLOWED_MISSES\n                    && let Some((v, sid, slot)) = val_obj.resolve_to_slot(&self.globals, n)\n                {\n                    next_sidecar.set(Some(OpcodeSidecar::ReadAttribute(ReadAttributeSidecar {\n                        misses: current_misses,\n                        shape_id: sid,\n                        slot_id: slot,\n                    })));\n                    frame.stack.push(v);\n                    return Ok(OpcodeRunExit::Continue);\n                }\n\n                // if you're here, either you had no sidecar, or you did but your sidecar failed and you didn't get a valid\n                // alternative slot to try (or you would have returned in the earlier if) - record where you're at (if you had a\n                // sidecar to begin with), and then do a full slow path attribute read\n                if let Some(sc) = current_sidecar {\n                    next_sidecar.set(Some(OpcodeSidecar::ReadAttribute(ReadAttributeSidecar {\n                        misses: current_misses,\n                        shape_id: sc.shape_id,\n                        slot_id: sc.slot_id,\n                    })));\n                }\n\n                match val_obj.read_attribute(n, &self.globals) {\n                    Ok(val) => {\n                        frame.stack.push(val);\n                    }\n                    Err(err) => {\n                        return build_vm_error!(\n                            match err {\n                                crate::runtime_value::AttributeError::NoSuchAttribute => {\n                                    VmErrorReason::NoSuchSymbol(n.0, SymbolKind::Identifier)\n                                }\n                                crate::runtime_value::AttributeError::InvalidFunctionBinding => {\n                                    VmErrorReason::InvalidBinding\n                                }\n                                crate::runtime_value::AttributeError::ValueHasNoAttributes => {\n                                    VmErrorReason::UnexpectedType\n                                }\n                            },\n                            next,\n                            frame,\n                            op_idx\n                        );\n                    }\n                }\n            }\n            Opcode::WriteAttributeSymbol(n) => {\n                let val = pop_or_err!(next, frame, op_idx);\n                let obj = pop_or_err!(next, frame, op_idx);\n                match obj.write_attribute(crate::symbol::Symbol(n), val, &mut self.globals) {\n                    Ok(_) => {}\n                    Err(err) => {\n                        return build_vm_error!(\n                            match err {\n                                crate::runtime_value::AttributeError::NoSuchAttribute => {\n                                    VmErrorReason::NoSuchSymbol(n, SymbolKind::Identifier)\n                                }\n                                crate::runtime_value::AttributeError::InvalidFunctionBinding => {\n                                    VmErrorReason::InvalidBinding\n                                }\n                                crate::runtime_value::AttributeError::ValueHasNoAttributes => {\n                                    VmErrorReason::UnexpectedType\n                                }\n                            },\n                            next,\n                            frame,\n                            op_idx\n                        );\n                    }\n                }\n            }\n            Opcode::LogicalAnd => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Boolean(a), RuntimeValue::Boolean(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(a & b));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::LogicalOr => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Boolean(a), RuntimeValue::Boolean(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(a | b));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::Xor => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Boolean(a), RuntimeValue::Boolean(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Boolean(a ^ b));\n                } else if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Integer(a ^ b));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::xor(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::BitwiseAnd => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Integer(a & b));\n                } else if let Ok(x) = IsaCheckable::try_from(&x)\n                    && let Ok(y) = IsaCheckable::try_from(&y)\n                {\n                    frame.stack.push(RuntimeValue::TypeCheck(x & &y));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::bitwise_and(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::BitwiseOr => {\n                let x = pop_or_err!(next, frame, op_idx);\n                let y = pop_or_err!(next, frame, op_idx);\n                if let (RuntimeValue::Integer(a), RuntimeValue::Integer(b)) = (&x, &y) {\n                    frame.stack.push(RuntimeValue::Integer(a | b));\n                } else if let Ok(x) = IsaCheckable::try_from(&x)\n                    && let Ok(y) = IsaCheckable::try_from(&y)\n                {\n                    frame.stack.push(RuntimeValue::TypeCheck(x | &y));\n                } else {\n                    binop_eval!(\n                        (RuntimeValue::bitwise_or(&y, &x, frame, self)),\n                        next,\n                        frame,\n                        op_idx\n                    )\n                }\n            }\n            Opcode::JumpTrue(n) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                if let RuntimeValue::Boolean(v) = x {\n                    if *v.raw_value() {\n                        *op_idx = n as usize;\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::JumpFalse(n) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                if let RuntimeValue::Boolean(v) = x {\n                    if !v.raw_value() {\n                        *op_idx = n as usize;\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::JumpConditionally(t, f) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                if let Some(b) = x.as_boolean() {\n                    *op_idx = if *b.raw_value() { t } else { f } as usize;\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::Jump(n) => {\n                *op_idx = n as usize;\n            }\n            Opcode::JumpIfArgSupplied(arg, dest) => {\n                if frame.argc > arg {\n                    *op_idx = dest as usize;\n                }\n            }\n            Opcode::Call(argc) => {\n                let x = pop_or_err!(next, frame, op_idx);\n                match x.eval(argc, frame, self, false) {\n                    Ok(crate::runtime_value::CallResult::Ok(_)) => {}\n                    Ok(crate::runtime_value::CallResult::Exception(e)) => {\n                        return Ok(OpcodeRunExit::Exception(e));\n                    }\n                    Err(err) => {\n                        if err.loc.is_some() {\n                            return Err(err);\n                        } else {\n                            return build_vm_error!(err.reason, next, frame, op_idx);\n                        }\n                    }\n                }\n            }\n            Opcode::Return => {\n                return Ok(OpcodeRunExit::Return);\n            }\n            Opcode::ReturnUnit => {\n                return match self.globals.create_unit_object() {\n                    Ok(unit) => {\n                        frame.stack.push(unit);\n                        Ok(OpcodeRunExit::Return)\n                    }\n                    Err(e) => {\n                        build_vm_error!(e, next, frame, op_idx)\n                    }\n                };\n            }\n            Opcode::TryEnter(offset) => {\n                frame\n                    .ctrl_blocks\n                    .push(crate::frame::ControlBlock::Try(offset));\n            }\n            Opcode::TryExit => match frame.ctrl_blocks.try_pop() {\n                Some(block) => match block {\n                    crate::frame::ControlBlock::Try(_) => {}\n                },\n                _ => {\n                    return build_vm_error!(VmErrorReason::EmptyStack, next, frame, op_idx);\n                }\n            },\n            Opcode::Throw => {\n                let ev = pop_or_err!(next, frame, op_idx);\n                match frame.drop_to_first_try(self) {\n                    Some(catch_offset) => {\n                        *op_idx = catch_offset as usize;\n                        frame.stack.push(ev);\n                    }\n                    None => {\n                        let e = VmException::from_value(ev);\n                        return Ok(OpcodeRunExit::Exception(e));\n                    }\n                };\n            }\n            Opcode::BuildList(n) => {\n                let values = (0..n).map(|_| frame.stack.try_pop()).collect::<Vec<_>>();\n                let list = List::default();\n                for value in values.iter().rev() {\n                    list.append(match value {\n                        Some(x) => x.clone(),\n                        None => {\n                            return build_vm_error!(VmErrorReason::EmptyStack, next, frame, op_idx);\n                        }\n                    });\n                }\n                let list = RuntimeValue::List(list);\n                frame.stack.push(list);\n            }\n            Opcode::BuildFunction => {\n                let val = pop_or_err!(next, frame, op_idx);\n                if let Some(co) = val.as_code_object() {\n                    let f = Function::from_code_object(co, this_module);\n                    frame.stack.push(RuntimeValue::Function(f));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::BuildStruct => {\n                let name = pop_or_err!(next, frame, op_idx);\n                if let Some(name) = name.as_string() {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Type(RuntimeValueType::Struct(Struct::new(\n                            name.raw_value(),\n                        ))));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::BuildEnum => {\n                let name = pop_or_err!(next, frame, op_idx);\n                if let Some(name) = name.as_string() {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Type(RuntimeValueType::Enum(Enum::new(\n                            name.raw_value(),\n                        ))));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::BuildMixin => {\n                let name = pop_or_err!(next, frame, op_idx);\n                if let Some(name) = name.as_string() {\n                    frame\n                        .stack\n                        .push(RuntimeValue::Mixin(Mixin::new(name.raw_value())));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::IncludeMixin => {\n                let mixin = pop_or_err!(next, frame, op_idx);\n                let struk = pop_or_err!(next, frame, op_idx);\n\n                if let (Some(mixin), Some(strukt)) = (mixin.as_mixin(), struk.as_struct()) {\n                    strukt.include_mixin(mixin);\n                } else if let (Some(mixin), Some(enumm)) = (mixin.as_mixin(), struk.as_enum()) {\n                    enumm.include_mixin(mixin);\n                } else if let (Some(mixin), Some(btt)) = (mixin.as_mixin(), struk.as_rust_native())\n                {\n                    btt.include_mixin(mixin);\n                } else if let (Some(src_mixin), Some(dst_mixin)) =\n                    (mixin.as_mixin(), struk.as_mixin())\n                {\n                    dst_mixin.include_mixin(src_mixin);\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::BindCase(..) => {\n                return build_vm_error!(\n                    VmErrorReason::UnknownOpcode(OPCODE_BIND_CASE),\n                    next,\n                    frame,\n                    op_idx\n                );\n            }\n            Opcode::BindCaseSymbol(a, n) => {\n                let payload_type = if (a & CASE_HAS_PAYLOAD) == CASE_HAS_PAYLOAD {\n                    let t = pop_or_err!(next, frame, op_idx);\n                    if let Ok(t) = IsaCheckable::try_from(&t) {\n                        Some(t)\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    None\n                };\n\n                let new_case = EnumCase {\n                    name: crate::symbol::Symbol(n),\n                    payload_type,\n                };\n\n                let enumm = pop_or_err!(next, frame, op_idx);\n\n                match enumm.as_enum() {\n                    Some(enumm) => {\n                        enumm.add_case(&mut self.globals, new_case);\n                    }\n                    _ => {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                }\n            }\n            Opcode::NewEnumVal(..) => {\n                return build_vm_error!(\n                    VmErrorReason::UnknownOpcode(OPCODE_NEW_ENUM_VAL),\n                    next,\n                    frame,\n                    op_idx\n                );\n            }\n            Opcode::EnumCheckIsCase(_) => {\n                return build_vm_error!(\n                    VmErrorReason::UnknownOpcode(OPCODE_ENUM_CHECK_IS_CASE),\n                    next,\n                    frame,\n                    op_idx\n                );\n            }\n            Opcode::NewEnumValSymbol(a, n) => {\n                let has_payload = (a & CASE_HAS_PAYLOAD) == CASE_HAS_PAYLOAD;\n                let case_sym = crate::symbol::Symbol(n);\n\n                let enumm = pop_or_err!(next, frame, op_idx);\n                let enumm = if let Some(enumm) = enumm.as_enum() {\n                    enumm\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n\n                let mut create_enum_payload =\n                    |case: &EnumCase,\n                     cidx,\n                     has_payload|\n                     -> ExecutionResult<OpcodeRunExit, VmError> {\n                        if case.payload_type.is_some() != has_payload {\n                            return build_vm_error!(\n                                VmErrorReason::UnexpectedType,\n                                next,\n                                frame,\n                                op_idx\n                            );\n                        }\n\n                        let payload = match &case.payload_type {\n                            Some(pt) => {\n                                let pv = pop_or_err!(next, frame, op_idx);\n                                if !pt.isa_check(&pv, &self.globals) {\n                                    return build_vm_error!(\n                                        VmErrorReason::UnexpectedType,\n                                        next,\n                                        frame,\n                                        op_idx\n                                    );\n                                } else {\n                                    Some(pv)\n                                }\n                            }\n                            None => None,\n                        };\n                        let ev = enumm.make_value(cidx, payload).unwrap();\n                        frame.stack.push(RuntimeValue::EnumValue(ev));\n                        Ok(OpcodeRunExit::Continue)\n                    };\n\n                let current_sidecar = next_sidecar\n                    .get()\n                    .and_then(|sc| sc.as_new_enum_val().copied());\n                let mut current_misses = current_sidecar\n                    .as_ref()\n                    .map(|sc| sc.misses)\n                    .unwrap_or_default();\n\n                let case_shape = enumm.case_shape_id();\n\n                if let Some(sc) = current_sidecar\n                    && current_misses < NewEnumValSidecar::MAXIMUM_ALLOWED_MISSES\n                    && sc.shape_id == case_shape\n                    && let Some(case) = enumm.get_case_by_idx(sc.slot_id.0 as usize)\n                {\n                    return create_enum_payload(&case, sc.slot_id.0 as usize, has_payload);\n                } else {\n                    current_misses = current_misses\n                        .saturating_add(1)\n                        .clamp(0, NewEnumValSidecar::MAXIMUM_ALLOWED_MISSES);\n                }\n\n                if current_misses < NewEnumValSidecar::MAXIMUM_ALLOWED_MISSES\n                    && let Some((shape_id, slot_id)) =\n                        enumm.resolve_to_slot(&self.globals, case_sym)\n                {\n                    let cidx = slot_id.0 as usize;\n                    if let Some(case) = enumm.get_case_by_idx(cidx) {\n                        next_sidecar.set(Some(OpcodeSidecar::NewEnumVal(NewEnumValSidecar {\n                            misses: current_misses,\n                            shape_id,\n                            slot_id,\n                        })));\n\n                        return create_enum_payload(&case, cidx, has_payload);\n                    }\n                }\n\n                // if you're here, either you had no sidecar, or you did but your sidecar failed and you didn't get a valid\n                // alternative slot to try (or you would have returned in the earlier if) - record where you're at (if you had a\n                // sidecar to begin with), and then do a full slow path attribute read\n                if let Some(sc) = current_sidecar {\n                    next_sidecar.set(Some(OpcodeSidecar::NewEnumVal(NewEnumValSidecar {\n                        misses: current_misses,\n                        shape_id: sc.shape_id,\n                        slot_id: sc.slot_id,\n                    })));\n                }\n\n                if let Some(cidx) = enumm.get_idx_of_case_by_symbol(&self.globals, case_sym)\n                    && let Some(case) = enumm.get_case_by_idx(cidx)\n                {\n                    return create_enum_payload(&case, cidx, has_payload);\n                } else {\n                    return build_vm_error!(\n                        VmErrorReason::NoSuchSymbol(case_sym.0, SymbolKind::Case),\n                        next,\n                        frame,\n                        op_idx\n                    );\n                }\n            }\n            Opcode::EnumCheckIsCaseSymbol(n) => {\n                let case_sym = crate::symbol::Symbol(n);\n                let ev = pop_or_err!(next, frame, op_idx);\n                let ev = if let Some(ev) = ev.as_enum_value() {\n                    ev\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n\n                let current_sidecar = next_sidecar\n                    .get()\n                    .and_then(|sc| sc.as_enum_check_is_case().copied());\n                let mut current_misses = current_sidecar\n                    .as_ref()\n                    .map(|sc| sc.misses)\n                    .unwrap_or_default();\n\n                let case_shape = ev.get_container_enum().case_shape_id();\n\n                if let Some(sc) = current_sidecar\n                    && current_misses < NewEnumValSidecar::MAXIMUM_ALLOWED_MISSES\n                    && sc.shape_id == case_shape\n                    && sc.slot_id.0 as usize == ev.get_case_index()\n                {\n                    frame.stack.push(RuntimeValue::Boolean(true.into()));\n                    return Ok(OpcodeRunExit::Continue);\n                } else {\n                    current_misses = current_misses\n                        .saturating_add(1)\n                        .clamp(0, NewEnumValSidecar::MAXIMUM_ALLOWED_MISSES);\n                }\n\n                if current_misses < NewEnumValSidecar::MAXIMUM_ALLOWED_MISSES\n                    && let Some((shape_id, slot_id)) = ev\n                        .get_container_enum()\n                        .resolve_to_slot(&self.globals, case_sym)\n                    && slot_id.0 as usize == ev.get_case_index()\n                {\n                    next_sidecar.set(Some(OpcodeSidecar::EnumCheckIsCase(\n                        EnumCheckIsCaseSidecar {\n                            misses: current_misses,\n                            shape_id,\n                            slot_id,\n                        },\n                    )));\n\n                    frame.stack.push(RuntimeValue::Boolean(true.into()));\n                    return Ok(OpcodeRunExit::Continue);\n                }\n\n                // if you're here, either you had no sidecar, or you did but your sidecar failed and you didn't get a valid\n                // alternative slot to try (or you would have returned in the earlier if) - record where you're at (if you had a\n                // sidecar to begin with), and then do a full slow path attribute read\n                if let Some(sc) = current_sidecar {\n                    next_sidecar.set(Some(OpcodeSidecar::EnumCheckIsCase(\n                        EnumCheckIsCaseSidecar {\n                            misses: current_misses,\n                            shape_id: sc.shape_id,\n                            slot_id: sc.slot_id,\n                        },\n                    )));\n                }\n\n                let is_case = match ev\n                    .get_container_enum()\n                    .get_idx_of_case_by_symbol(&self.globals, case_sym)\n                {\n                    Some(idx) => idx == ev.get_case_index(),\n                    None => false,\n                };\n                frame.stack.push(RuntimeValue::Boolean(is_case.into()));\n            }\n            Opcode::EnumTryExtractPayload => {\n                let ev = pop_or_err!(next, frame, op_idx);\n                if let Some(ev) = ev.as_enum_value() {\n                    let p = ev.get_payload();\n                    match p {\n                        None => {\n                            frame.stack.push(RuntimeValue::Boolean(false.into()));\n                        }\n                        Some(p) => {\n                            frame.stack.push(p.clone());\n                            frame.stack.push(RuntimeValue::Boolean(true.into()));\n                        }\n                    }\n                } else {\n                    frame.stack.push(RuntimeValue::Boolean(false.into()));\n                }\n            }\n            Opcode::TryUnwrapProtocol(mode) => {\n                let result_enum = if let Some(re) = self\n                    .globals\n                    .get_builtin_type_by_id(BuiltinTypeId::Result)\n                    .as_enum()\n                {\n                    re.clone()\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedVmState, next, frame, op_idx);\n                };\n                let maybe_enum = if let Some(re) = self\n                    .globals\n                    .get_builtin_type_by_id(BuiltinTypeId::Maybe)\n                    .as_enum()\n                {\n                    re.clone()\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedVmState, next, frame, op_idx);\n                };\n\n                let val = pop_or_err!(next, frame, op_idx);\n                let ev = if let Some(ev) = val.as_enum_value() {\n                    if ev.get_container_enum() == &maybe_enum\n                        || ev.get_container_enum() == &result_enum\n                    {\n                        ev.clone()\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n\n                let case_index = ev.get_case_index();\n                match case_index {\n                    0 => {\n                        // Ok/Some\n                        if let Some(case_value) = ev.get_payload() {\n                            frame.stack.push(case_value.clone());\n                            if mode == haxby_opcodes::try_unwrap_protocol_mode::FLAG_TO_CALLER {\n                                frame.stack.push(RuntimeValue::Boolean(true.into()));\n                            }\n                        } else {\n                            return build_vm_error!(\n                                VmErrorReason::EnumWithoutPayload,\n                                next,\n                                frame,\n                                op_idx\n                            );\n                        }\n                    }\n                    1 => {\n                        // Err/None\n                        match mode {\n                            haxby_opcodes::try_unwrap_protocol_mode::PROPAGATE_ERROR => {\n                                frame.stack.push(val.clone());\n                                return Ok(OpcodeRunExit::Return); // implement a Return\n                            }\n                            haxby_opcodes::try_unwrap_protocol_mode::FLAG_TO_CALLER => {\n                                frame.stack.push(val.clone());\n                                frame.stack.push(RuntimeValue::Boolean(false.into()));\n                            }\n                            haxby_opcodes::try_unwrap_protocol_mode::ASSERT_ERROR => {\n                                return build_vm_error!(\n                                    VmErrorReason::AssertFailed(\"force unwrap failed\".to_string()),\n                                    next,\n                                    frame,\n                                    op_idx\n                                );\n                            }\n                            _ => {\n                                // should never happen\n                                return build_vm_error!(\n                                    VmErrorReason::IncompleteInstruction,\n                                    next,\n                                    frame,\n                                    op_idx\n                                );\n                            }\n                        }\n                    }\n                    _ => {\n                        // should never happen\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                }\n            }\n            Opcode::Isa => {\n                let t = pop_or_err!(next, frame, op_idx);\n                let val = pop_or_err!(next, frame, op_idx);\n                if let Ok(isa_check) = IsaCheckable::try_from(&t) {\n                    frame.stack.push(RuntimeValue::Boolean(\n                        isa_check.isa_check(&val, &self.globals).into(),\n                    ));\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                }\n            }\n            Opcode::Assert(n) => {\n                let assert_msg = if let Some(ct) = this_module.load_indexed_const(n) {\n                    if let Some(sv) = ct.as_string() {\n                        sv.raw_value()\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n\n                let x = pop_or_err!(next, frame, op_idx);\n                if let Some(b) = x.as_boolean() {\n                    if !*b.raw_value() {\n                        return build_vm_error!(\n                            VmErrorReason::AssertFailed(assert_msg.to_owned()),\n                            next,\n                            frame,\n                            op_idx\n                        );\n                    }\n                } else {\n                    return build_vm_error!(\n                        VmErrorReason::AssertFailed(assert_msg.to_owned()),\n                        next,\n                        frame,\n                        op_idx\n                    );\n                }\n            }\n            Opcode::Halt => {\n                return build_vm_error!(VmErrorReason::VmHalted, next, frame, op_idx);\n            }\n            Opcode::LoadDylib(n) => {\n                let module = pop_or_err!(next, frame, op_idx);\n                let module = match module.as_module() {\n                    Some(m) => m,\n                    None => {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                };\n\n                let lib_name = if let Some(ct) = this_module.load_indexed_const(n) {\n                    if let Some(sv) = ct.as_string() {\n                        sv.raw_value()\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n\n                // this means that one cannot use the same dylib for multiple modules!\n                #[allow(clippy::map_entry)]\n                if !self.loaded_dylibs.contains_key(lib_name) {\n                    unsafe {\n                        let dylib_path = get_lib_path(lib_name);\n                        let dylib = match libloading::Library::new(&dylib_path) {\n                            Ok(d) => d,\n                            Err(e) => {\n                                return build_vm_error!(\n                                    VmErrorReason::ImportNotAvailable(\n                                        dylib_path.into_os_string().into_string().unwrap(),\n                                        e.to_string()\n                                    ),\n                                    next,\n                                    frame,\n                                    op_idx\n                                );\n                            }\n                        };\n                        let symbol: libloading::Symbol<\n                            unsafe extern \"C\" fn(\n                                *mut VirtualMachine,\n                                *const RuntimeModule,\n                            ) -> LoadResult,\n                        > = match dylib.get(b\"dylib_haxby_inject\") {\n                            Ok(f) => f,\n                            Err(e) => {\n                                return build_vm_error!(\n                                    VmErrorReason::ImportNotAvailable(\n                                        dylib_path.into_os_string().into_string().unwrap(),\n                                        e.to_string()\n                                    ),\n                                    next,\n                                    frame,\n                                    op_idx\n                                );\n                            }\n                        };\n\n                        let load_result =\n                            symbol(self as *mut VirtualMachine, module as *const RuntimeModule);\n                        if load_result.status == LoadStatus::Success {\n                            self.loaded_dylibs.insert(lib_name.to_owned(), dylib);\n                        } else {\n                            let msg = load_result.into_rust_string();\n                            return build_vm_error!(\n                                VmErrorReason::ImportNotAvailable(lib_name.to_owned(), msg),\n                                next,\n                                frame,\n                                op_idx\n                            );\n                        }\n                    }\n                }\n            }\n            Opcode::LiftModule => {\n                let dest = pop_or_err!(next, frame, op_idx);\n                let dest = if let Some(m) = dest.as_module() {\n                    m\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n                let src = pop_or_err!(next, frame, op_idx);\n                let src = if let Some(m) = src.as_module() {\n                    m\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n                match dest.lift_all_symbols_from_other(src, self) {\n                    Ok(_) => {}\n                    Err(e) => {\n                        return build_vm_error!(e, next, frame, op_idx);\n                    }\n                }\n            }\n            Opcode::Import(n) => {\n                let ipath = if let Some(ct) = this_module.load_indexed_const(n) {\n                    if let Some(sv) = ct.as_string() {\n                        sv.raw_value()\n                    } else {\n                        return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                    }\n                } else {\n                    return build_vm_error!(VmErrorReason::UnexpectedType, next, frame, op_idx);\n                };\n\n                if let Some(mli) = self.imported_modules.get(ipath) {\n                    if let Err(e) = Self::create_import_model_from_path(\n                        this_module,\n                        &mut self.globals,\n                        ipath,\n                        RuntimeValue::Module(mli.module.clone()),\n                    ) {\n                        return build_vm_error!(e, next, frame, op_idx);\n                    }\n\n                    frame.stack.push(RuntimeValue::Module(mli.module.clone()));\n                } else {\n                    let import_path = match Self::resolve_import_path_to_path(\n                        ipath,\n                        this_module.get_compiled_module().widget_root_path.as_ref(),\n                    ) {\n                        Ok(ipath) => ipath,\n                        Err(err) => {\n                            return build_vm_error!(err, next, frame, op_idx);\n                        }\n                    };\n\n                    let sb = match SourceBuffer::from_path(&import_path) {\n                        Ok(sb) => sb,\n                        Err(_) => {\n                            return build_vm_error!(\n                                VmErrorReason::ImportNotAvailable(\n                                    ipath.to_owned(),\n                                    \"no such file\".to_owned()\n                                ),\n                                next,\n                                frame,\n                                op_idx\n                            );\n                        }\n                    };\n\n                    if self.import_stack.contains(ipath) {\n                        return build_vm_error!(\n                            VmErrorReason::CircularImport(ipath.to_owned()),\n                            next,\n                            frame,\n                            op_idx\n                        );\n                    } else {\n                        self.import_stack.push(ipath.clone());\n                    }\n\n                    let c_module = match compile_from_source(&sb, &Default::default()) {\n                        Ok(cm) => cm,\n                        Err(ces) => {\n                            let err_msg = ces\n                                .iter()\n                                .map(|x| format!(\"error: {x}\"))\n                                .collect::<Vec<_>>()\n                                .join(\"\\n\");\n                            assert!(*ipath == self.import_stack.pop());\n                            return build_vm_error!(\n                                VmErrorReason::ImportNotAvailable(\n                                    ipath.to_owned(),\n                                    format!(\"module failed to compile: {err_msg}\")\n                                ),\n                                next,\n                                frame,\n                                op_idx\n                            );\n                        }\n                    };\n                    let mli = match self.load_module(&sb.name, c_module)? {\n                        RunloopExit::Ok(mli) => mli,\n                        RunloopExit::Exception(e) => {\n                            assert!(*ipath == self.import_stack.pop());\n                            return Ok(OpcodeRunExit::Exception(e));\n                        }\n                    };\n\n                    if let Err(e) = Self::create_import_model_from_path(\n                        this_module,\n                        &mut self.globals,\n                        ipath,\n                        RuntimeValue::Module(mli.module.clone()),\n                    ) {\n                        return build_vm_error!(e, next, frame, op_idx);\n                    }\n\n                    assert!(*ipath == self.import_stack.pop());\n\n                    frame.stack.push(RuntimeValue::Module(mli.module.clone()));\n\n                    self.imported_modules.insert(ipath.to_owned(), mli);\n                };\n            }\n        }\n\n        Ok(OpcodeRunExit::Continue)\n    }\n\n    fn runloop(\n        &mut self,\n        bc: &[Opcode],\n        sidecar: &SidecarSlice,\n        module: &RuntimeModule,\n        frame: &mut Frame,\n    ) -> ExecutionResult<RunloopExit, VmError> {\n        let mut op_counter = 0;\n        loop {\n            #[cfg(debug_assertions)]\n            if self.options.tracing && self.options.dump_stack {\n                frame.stack.dump();\n            }\n\n            let next = match bc.get(op_counter) {\n                Some(op) => *op,\n                None => {\n                    return Err(VmErrorReason::UnterminatedBytecode.into());\n                }\n            };\n\n            let next_sidecar = match sidecar.get(op_counter) {\n                Some(sc) => sc,\n                None => {\n                    return Err(VmErrorReason::UnterminatedBytecode.into());\n                }\n            };\n\n            #[cfg(debug_assertions)]\n            if self.options.tracing {\n                let poa = aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator::default();\n                let next = {\n                    let ropc = crate::opcodes::prettyprint::RuntimeOpcodePrinter {\n                        globals: Some(&self.globals),\n                        module: Some(module),\n                    };\n                    crate::opcodes::prettyprint::opcode_prettyprint(next, &ropc, poa).value()\n                };\n                let next_sidecar = {\n                    if let Some(sc) = next_sidecar.get() {\n                        let poa = aria_parser::ast::prettyprint::printout_accumulator::PrintoutAccumulator::default();\n                        crate::opcodes::sidecar::sidecar_prettyprint(sc, poa).value()\n                    } else {\n                        \"\".to_string()\n                    }\n                };\n                let wrote_lt = if let Some(lt) = frame.get_line_entry_at_pos(op_counter as u16) {\n                    println!(\"{op_counter:05}: {next} {next_sidecar} --> {lt}\");\n                    true\n                } else {\n                    false\n                };\n                if !wrote_lt {\n                    println!(\"{op_counter:05}: {next} {next_sidecar}\");\n                }\n            }\n\n            // we save the original counter (the current instruction) for two reasons:\n            // - if an exception occurs, we need to figure out where we came from to build the backtrace\n            // - run_opcode does not advance the counter unless it's jumping, so we need to know if it changed\n            //   and if not advance it ourselves\n            let current_op_counter = op_counter;\n\n            // some errors can be converted into exceptions, so reserve the right to postpone exception handling\n            let mut need_handle_exception: Option<VmException> = None;\n\n            match self.run_opcode(next, next_sidecar, &mut op_counter, module, frame) {\n                Ok(OpcodeRunExit::Continue) => {}\n                Ok(OpcodeRunExit::Return) => {\n                    return Ok(RunloopExit::Ok(()));\n                }\n                Ok(OpcodeRunExit::Exception(except)) => {\n                    need_handle_exception = Some(except);\n                }\n                Err(x) => match VmException::from_vmerror(x, &mut self.globals) {\n                    Ok(exception) => {\n                        need_handle_exception = Some(exception);\n                    }\n                    Err(err) => {\n                        let err = if let Some(lt) =\n                            frame.get_line_entry_at_pos(current_op_counter as u16)\n                        {\n                            let mut new_err = err.clone();\n                            new_err.backtrace.push(lt);\n                            new_err\n                        } else {\n                            err\n                        };\n                        return Err(err);\n                    }\n                },\n            }\n\n            if op_counter == current_op_counter {\n                op_counter += 1;\n            }\n\n            if let Some(except) = need_handle_exception {\n                except.fill_in_backtrace(&mut self.globals);\n                match frame.drop_to_first_try(self) {\n                    Some(o) => {\n                        op_counter = o as usize;\n                        frame.stack.push(except.value);\n                    }\n                    None => {\n                        let new_except = if let Some(lt) =\n                            frame.get_line_entry_at_pos(current_op_counter as u16)\n                        {\n                            except.thrown_at(lt)\n                        } else {\n                            except\n                        };\n                        return Ok(RunloopExit::Exception(new_except));\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vscode/aria/.vscodeignore",
    "content": ".env\nbuild.sh\nsrc/"
  },
  {
    "path": "vscode/aria/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2024 Enrico Granata\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n   "
  },
  {
    "path": "vscode/aria/README.md",
    "content": "# Aria\n\nThis is the VSCode syntax highlighter extension for the Aria language\n\n## Known Issues\n\n* No cross-file go to definition support\n* Only displays parse errors and messages could be clearer\n\n**Enjoy!**\n"
  },
  {
    "path": "vscode/aria/build.sh",
    "content": "#!/bin/sh\n\n[ -f ./.env ] && . ./.env\n\nEDITOR_CLI=\"${EDITOR_CLI:-${EDITOR_CMD:-${EDITOR:-${VSCODE_CLI:-code}}}}\"\n\ncargo build --manifest-path ../../lsp/Cargo.toml && \\\nvsce package --allow-missing-repository && \\\n\"$EDITOR_CLI\" --install-extension ./aria-0.0.1.vsix\n\n# sadly, the vscode window will still need to be reloaded after running this"
  },
  {
    "path": "vscode/aria/language-configuration.json",
    "content": "{\n    \"comments\": {\n        // symbol used for single line comment. Remove this entry if your language does not support line comments\n        \"lineComment\": \"#\",\n    },\n    // symbols used as brackets\n    \"brackets\": [\n        [\"{\", \"}\"],\n        [\"[\", \"]\"],\n        [\"(\", \")\"]\n    ],\n    // symbols that are auto closed when typing\n    \"autoClosingPairs\": [\n        [\"{\", \"}\"],\n        [\"[\", \"]\"],\n        [\"(\", \")\"],\n        [\"\\\"\", \"\\\"\"],\n        [\"'\", \"'\"]\n    ],\n    // symbols that can be used to surround a selection\n    \"surroundingPairs\": [\n        [\"{\", \"}\"],\n        [\"[\", \"]\"],\n        [\"(\", \")\"],\n        [\"\\\"\", \"\\\"\"],\n        [\"'\", \"'\"]\n    ]\n}"
  },
  {
    "path": "vscode/aria/package.json",
    "content": "{\n  \"name\": \"aria\",\n  \"displayName\": \"Aria\",\n  \"description\": \"Aria Language Support\",\n  \"version\": \"0.0.1\",\n  \"engines\": {\n    \"vscode\": \"^1.100.0\"\n  },\n  \"categories\": [\n    \"Programming Languages\"\n  ],\n\t\"main\": \"./out/extension.js\",\n  \"contributes\": {\n    \"languages\": [\n      {\n        \"id\": \"aria\",\n        \"aliases\": [\n          \"Aria\",\n          \"aria\"\n        ],\n        \"extensions\": [\n          \".aria\"\n        ],\n        \"configuration\": \"./language-configuration.json\"\n      }\n    ],\n    \"configuration\": {\n      \"title\": \"Aria\",\n      \"properties\": {\n        \"aria.lsp.serverPath\": {\n          \"type\": \"string\",\n          \"default\": \"\",\n          \"description\": \"Path to Aria LSP executable. Leave empty to use ../target/debug/lsp relative to this extension.\"\n        }\n      }\n    },\n    \"grammars\": [\n      {\n        \"language\": \"aria\",\n        \"scopeName\": \"source.aria\",\n        \"path\": \"./syntaxes/aria.tmLanguage.json\"\n      }\n    ]\n  },\n  \"dependencies\": {\n\t\t\"glob\": \"^11.1.0\",\n\t\t\"vscode-languageclient\": \"^9.0.1\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@types/vscode\": \"^1.100.0\",\n\t\t\"@vscode/test-electron\": \"^2.3.9\",\n\t\t\"typescript\": \"^5.9.2\",\n\t\t\"typescript-eslint\": \"^8.39.0\",\n\t\t\"@types/mocha\": \"^10.0.6\",\n\t\t\"@types/node\": \"^22\"\n\t},\n\t\"scripts\": {\n\t\t\"vscode:prepublish\": \"npm run compile\",\n\t\t\"compile\": \"tsc -b\",\n\t\t\"watch\": \"tsc -b -w\",\n\t\t\"lint\": \"eslint\",\n\t\t\"test\": \"sh ./scripts/e2e.sh\"\n\t}\n}\n"
  },
  {
    "path": "vscode/aria/src/extension.ts",
    "content": "import { workspace, EventEmitter, ExtensionContext, Uri } from \"vscode\";\n\nimport {\n  Disposable,\n  Executable,\n  LanguageClient,\n  LanguageClientOptions,\n  ServerOptions,\n} from \"vscode-languageclient/node\";\n\nlet client: LanguageClient;\nexport async function activate(context: ExtensionContext) {\n\n\tconst configuredPath = workspace.getConfiguration('aria').get<string>('lsp.serverPath')?.trim();\n\tconst envPath = process.env.ARIA_LSP_PATH?.trim();\n\tconst defaultUri = Uri.joinPath(context.extensionUri, '..', '..', 'target', 'debug', 'lsp');\n\tconst command = configuredPath || envPath || defaultUri.fsPath;\n\tconst run: Executable = {\n\t\tcommand,\n\t\toptions: {\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\tRUST_LOG: \"debug\",\n\t\t},\n\t\t},\n\t};\n\t\n  const serverOptions: ServerOptions = {\n\t\trun,\n\t\tdebug: run,\n\t};\n\n\tconst clientOptions: LanguageClientOptions = {\n\t\tdocumentSelector: [{ scheme: \"file\", language: \"aria\" }],\n\t\tsynchronize: {\n\t\tfileEvents: workspace.createFileSystemWatcher(\"**/.clientrc\"),\n\t\t}\n\t};\n\n\tclient = new LanguageClient(\"aria-language-server\", \"aria language server\", serverOptions, clientOptions);\n\tclient.start();\n}\n\nexport function deactivate(): Thenable<void> | undefined {\n  if (!client) {\n    return undefined;\n  }\n  return client.stop();\n}\n\nexport function activateInlayHints(ctx: ExtensionContext) {\n  const maybeUpdater = {\n    hintsProvider: null as Disposable | null,\n    updateHintsEventEmitter: new EventEmitter<void>(),\n\n    async onConfigChange() {\n      this.dispose();\n      // TODO: reload the lsp connection if path changed  \n    },\n\n    dispose() {\n      this.hintsProvider?.dispose();\n      this.hintsProvider = null;\n      this.updateHintsEventEmitter.dispose();\n    },\n  };\n\n  workspace.onDidChangeConfiguration(maybeUpdater.onConfigChange, maybeUpdater, ctx.subscriptions);\n\n  maybeUpdater.onConfigChange().catch(console.error);\n}"
  },
  {
    "path": "vscode/aria/syntaxes/aria.tmLanguage.json",
    "content": "{\n\t\"$schema\": \"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json\",\n\t\"name\": \"Aria\",\n\t\"patterns\": [\n\t\t{\n\t\t\t\"include\": \"#keywords\"\n\t\t},\n\t\t{\n\t\t\t\"include\": \"#strings\"\n\t\t},\n\t\t{\n\t\t\t\"include\": \"#booleans\"\n\t\t},\n\t\t{\n\t\t\t\"include\": \"#numbers\"\n\t\t},\n\t\t{\n\t\t\t\"include\": \"#identifiers\"\n\t\t}\n\t],\n\t\"repository\": {\n\t\t\"keywords\": {\n\t\t\t\"patterns\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"comment.line.double-slash.aria\",\n\t\t\t\t\t\"match\": \"#.*$\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"keyword.control.aria\",\n\t\t\t\t\t\"match\": \"\\\\b(and|assert|break|case|catch|continue|enum|else|elsif|extension|for|from|guard|if|import|in|include|isa|func|match|mixin|operator|return|struct|throw|try|val|while)\\\\b\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"keyword.control.contextual.func.aria\",\n\t\t\t\t\t\"match\": \"\\\\b(instance|type)\\\\b(?=\\\\s+func)\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"keyword.control.contextual.op.aria\",\n\t\t\t\t\t\"match\": \"\\\\b(reverse)\\\\b(?=\\\\s+operator)\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"keyword.control.type-val.aria\",\n\t\t\t\t\t\"match\": \"\\\\btype\\\\s+val\\\\b\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"booleans\": {\n\t\t\t\"patterns\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"constant.language.boolean.aria\",\n\t\t\t\t\t\"match\": \"\\\\b(false|true)\\\\b\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"strings\": {\n\t\t\t\"patterns\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"string.quoted.double.aria\",\n\t\t\t\t\t\"begin\": \"\\\"\",\n\t\t\t\t\t\"end\": \"\\\"\",\n\t\t\t\t\t\"patterns\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"constant.character.escape.aria\",\n\t\t\t\t\t\t\t\"match\": \"\\\\\\\\.\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"string.quoted.single.aria\",\n\t\t\t\t\t\"begin\": \"'\",\n\t\t\t\t\t\"end\": \"'\",\n\t\t\t\t\t\"patterns\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"constant.character.escape.aria\",\n\t\t\t\t\t\t\t\"match\": \"\\\\\\\\.\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"numbers\": {\n\t\t\t\"patterns\": [\n\t\t\t\t{\n\t\t\t\t\t\"match\": \"\\\\b\\\\d+\\\\.\\\\d+f\\\\b\",\n\t\t\t\t\t\"name\": \"constant.numeric.float.aria\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"constant.numeric.decimal.aria\",\n\t\t\t\t\t\"match\": \"\\\\b\\\\d[\\\\d_]*\\\\b\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"constant.numeric.hexadecimal.aria\",\n\t\t\t\t\t\"match\": \"\\\\b0x[0-9a-fA-F][0-9a-fA-F_]*\\\\b\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"constant.numeric.binary.aria\",\n\t\t\t\t\t\"match\": \"\\\\b0b[01][01_]*\\\\b\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"identifiers\": {\n\t\t\t\"patterns\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"variable.other.aria\",\n\t\t\t\t\t\"match\": \"\\\\b[_\\\\p{L}][_\\\\p{L}\\\\p{M}\\\\p{Nd}\\\\p{Pc}\\\\p{Nl}]*\\\\b\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n\t\"scopeName\": \"source.aria\"\n}"
  },
  {
    "path": "vscode/aria/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"ES2024\",\n\t\t\"lib\": [\n\t\t\t\"ES2024\"\n\t\t],\n\t\t\"outDir\": \"out\",\n\t\t\"rootDir\": \"src\",\n\t\t\"sourceMap\": true\n\t},\n\t\"include\": [\n\t\t\"src\"\n\t],\n\t\"exclude\": [\n\t\t\"node_modules\",\n\t\t\".vscode-test\"\n\t]\n}"
  },
  {
    "path": "vscode/aria/tsconfig.tsbuildinfo",
    "content": "{\"root\":[\"./src/extension.ts\"],\"version\":\"5.9.3\"}"
  }
]