diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f2d5f1c84d..2395483b55 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -4,11 +4,13 @@ on: push: branches: - main + tags: + - 'v*' pull_request: branches: - main env: - MACOSX_DEPLOYMENT_TARGET: 12.0 + MACOSX_DEPLOYMENT_TARGET: 15.0 jobs: Build: @@ -17,13 +19,19 @@ jobs: strategy: fail-fast: false matrix: - os: ["ubuntu-latest", "macos-latest", "windows-2019"] + os: ["ubuntu-latest", "macos-latest", "windows-2025"] python-version: ["3.10"] steps: - uses: actions/checkout@v3 with: + submodules: true fetch-depth: 0 + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + - name: Cache conda uses: actions/cache@v3 env: @@ -33,32 +41,33 @@ jobs: key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('ci/environment.yml') }} - - uses: conda-incubator/setup-miniconda@v2 + - uses: mamba-org/setup-micromamba@v1.9.0 with: - auto-update-conda: true environment-file: ci/environment.yml - python-version: ${{ matrix.python-version }} - use-only-tar-bz2: true + create-args: >- + python=${{ matrix.python-version }} + cmake=3.30.0 + nodejs=18.20.5 - name: Install Windows Conda Packages if: contains(matrix.os, 'windows') - shell: bash -l {0} - run: conda install m2-bison=3.0.4 + shell: bash -e -l {0} + run: micromamba install --freeze-installed m2-bison=3.0.4 m2-filesystem - name: Install Linux / macOS Conda Packages if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') - shell: bash -l {0} - run: conda install bison=3.4 + shell: bash -e -l {0} + run: micromamba install --freeze-installed bison=3.4 - name: Conda info - shell: bash -l {0} + shell: bash -e -l {0} run: | - conda info - conda list + micromamba info + micromamba list - name: Setup Platform (Linux) if: contains(matrix.os, 'ubuntu') - shell: bash -l {0} + shell: bash -e -l {0} run: | echo "LFORTRAN_CMAKE_GENERATOR=Unix Makefiles" >> $GITHUB_ENV echo "WIN=0" >> $GITHUB_ENV @@ -67,7 +76,7 @@ jobs: - name: Setup Platform (macOS) if: contains(matrix.os, 'macos') - shell: bash -l {0} + shell: bash -e -l {0} run: | echo "LFORTRAN_CMAKE_GENERATOR=Unix Makefiles" >> $GITHUB_ENV echo "WIN=0" >> $GITHUB_ENV @@ -75,7 +84,7 @@ jobs: echo "ENABLE_RUNTIME_STACKTRACE=yes" >> $GITHUB_ENV - name: Build (Linux / macOS) - shell: bash -l {0} + shell: bash -e -l {0} if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') run: | xonsh ci/build.xsh @@ -84,18 +93,21 @@ jobs: if: contains(matrix.os, 'windows') shell: cmd run: | - set CONDA_INSTALL_LOCN=C:\\Miniconda - call %CONDA_INSTALL_LOCN%\Scripts\activate.bat - call conda activate test + set MAMBA_INSTALL_LOCN=C:\\Users\runneradmin\micromamba + call %MAMBA_INSTALL_LOCN%\Scripts\activate.bat + call micromamba activate lp set LFORTRAN_CMAKE_GENERATOR=Ninja set WIN=1 set MACOS=0 set ENABLE_RUNTIME_STACKTRACE=no - call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + set CC=cl.exe + set CXX=cl.exe + set "PATH=%PATH:C:\mingw64\bin;=%" # Remove mingw from path xonsh ci\build.xsh - name: Test (Linux / macOS) - shell: bash -l {0} + shell: bash -e -l {0} if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') run: | xonsh ci/test.xsh @@ -104,27 +116,36 @@ jobs: if: contains(matrix.os, 'windows') shell: cmd run: | - set CONDA_INSTALL_LOCN=C:\\Miniconda - call %CONDA_INSTALL_LOCN%\Scripts\activate.bat - call conda activate test + set MAMBA_INSTALL_LOCN=C:\\Users\runneradmin\micromamba + call %MAMBA_INSTALL_LOCN%\Scripts\activate.bat + call micromamba activate lp set LFORTRAN_CMAKE_GENERATOR=Ninja set WIN=1 set MACOS=0 - call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + set CC=cl.exe + set CXX=cl.exe + set "PATH=%PATH:C:\mingw64\bin;=%" # Remove mingw from path xonsh ci\test.xsh build_to_wasm: name: Build LPython to WASM - runs-on: "ubuntu-latest" + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: + submodules: true fetch-depth: 0 - - uses: mamba-org/provision-with-micromamba@main + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 with: environment-file: ci/environment.yml - extra-specs: | + create-args: >- python=3.10 bison=3.4 @@ -133,6 +154,13 @@ jobs: variant: sccache key: ${{ github.job }}-${{ matrix.os }} + - name : Remove existing node + shell: bash -l {0} + run : | + which node + node -v + sudo rm -rf /usr/local/bin/node /usr/local/bin/npm + - name: Install Emscripten from Git shell: bash -l {0} run: | @@ -142,13 +170,12 @@ jobs: git clone https://github.com/emscripten-core/emsdk.git cd emsdk - # Download and install the latest SDK tools. - ./emsdk install latest + ./emsdk install 3.1.35 + ./emsdk activate 3.1.35 + ./emsdk install node-18.20.3-64bit + ./emsdk activate node-18.20.3-64bit - # Make the "latest" SDK "active" for the current user. (writes .emscripten file) - ./emsdk activate latest - - - name: Show Emscripten Info + - name: Show Emscripten and Node Info shell: bash -l {0} run: | set -ex @@ -156,13 +183,14 @@ jobs: source $HOME/ext/emsdk/emsdk_env.sh emcc -v em++ -v + which node + node -v - name: Build to WASM shell: bash -l {0} run: | set -ex source $HOME/ext/emsdk/emsdk_env.sh # Activate Emscripten - ./build0.sh ./build_to_wasm.sh - name: Test built lpython.wasm @@ -170,4 +198,493 @@ jobs: run: | set -ex source $HOME/ext/emsdk/emsdk_env.sh # Activate Emscripten + which node + node -v node src/lpython/tests/test_lpython.js + + test_pip_pkgs: + name: Test PIP Installable Packages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + python=3.10 + bison=3.4 + + - uses: hendrikmuhs/ccache-action@main + with: + variant: sccache + key: ${{ github.job }}-${{ matrix.os }} + + - name: Build Linux + shell: bash -e -l {0} + run: | + ./build0.sh + cmake . -GNinja \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DLFORTRAN_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=yes \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + cmake --build . -j16 --target install + + - name: PIP show version + shell: bash -e -l {0} + run: | + python -m pip -V + + - name: PIP install required packages + shell: bash -e -l {0} + run: | + # Package lpynn has lpython_emulation as dependency + # Hence, it should by default install lpython_emulation + python -m pip install lpython_emulation==0.0.1.9 lpynn==0.0.1.4 numpy==1.24.3 + + - name: PIP show installed packages + shell: bash -e -l {0} + run: | + python -m pip list + + - name: Test PIP Packages with Python + shell: bash -e -l {0} + run: | + python integration_tests/test_pip_import_01.py + + # - name: Test PIP Packages with LPython + # shell: bash -e -l {0} + # run: | + # pip_pkg_path=$(python -c "import site; print(site.getsitepackages()[0])") + # echo $pip_pkg_path + # ./src/bin/lpython integration_tests/test_pip_import_01.py -I $pip_pkg_path + + debug: + name: Check Debug build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + python=3.10 + bison=3.4 + + - uses: hendrikmuhs/ccache-action@main + with: + variant: sccache + key: ${{ github.job }}-${{ matrix.os }} + + - name: Build Linux + shell: bash -e -l {0} + run: | + ./build0.sh + export CXXFLAGS="-Werror" + cmake . -GNinja \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DLFORTRAN_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=yes \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + cmake --build . -j16 --target install + + - name: Test Linux + shell: bash -e -l {0} + run: | + ctest + ./run_tests.py -s + cd integration_tests + ./run_tests.py -b llvm c + ./run_tests.py -b llvm c -f + + release: + name: Check Release build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + python=3.10 + bison=3.4 + + - uses: hendrikmuhs/ccache-action@main + with: + variant: sccache + key: ${{ github.job }}-${{ matrix.os }} + + - name: Build Linux + shell: bash -e -l {0} + run: | + ./build0.sh + export CXXFLAGS="-Werror" + cmake . -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_FLAGS_RELEASE="-Wall -Wextra -O3 -funroll-loops -DNDEBUG" \ + -DWITH_LLVM=yes \ + -DLFORTRAN_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=yes \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + cmake --build . -j16 --target install + + - name: Test Linux + shell: bash -e -l {0} + run: | + ctest --rerun-failed --output-on-failure + ./run_tests.py -s + cd integration_tests + ./run_tests.py -b llvm c + ./run_tests.py -b llvm c -f + + cpython_interop: + name: Test CPython Interop (@pythoncall) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + python=3.10 + bison=3.4 + + - uses: hendrikmuhs/ccache-action@main + with: + variant: sccache + key: ${{ github.job }}-${{ matrix.os }} + + - name: Build Linux + shell: bash -e -l {0} + run: | + ./build0.sh + cmake . -GNinja \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DLFORTRAN_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=yes \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + cmake --build . -j16 --target install + + - name: Test Linux + shell: bash -e -l {0} + run: | + cd integration_tests + ./run_tests.py -b cpython c_py llvm_py + ./run_tests.py -b cpython c_py llvm_py -f + + sympy: + name: Run SymPy tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + python=3.10 + bison=3.4 + symengine=0.12.0 + sympy=1.11.1 + + - uses: hendrikmuhs/ccache-action@main + with: + key: ${{ github.job }}-${{ matrix.os }} + + - name: Build + shell: bash -e -l {0} + run: | + ./build0.sh + cmake . -G"Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DLPYTHON_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=no \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + + cmake --build . -j16 --target install + + - name: Test + shell: bash -e -l {0} + run: | + cd integration_tests + ./run_tests.py -b c_sym cpython_sym llvm_sym llvm_jit + ./run_tests.py -b c_sym cpython_sym llvm_sym llvm_jit -f + + integration_tests_cpython: + name: Run Integration tests with Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-name: lp + condarc: | + channels: + - conda-forge + create-args: >- + llvmdev=11.1.0 + bison=3.4 + re2c=2.2 + zlib=1.3.1 + cmake=3.30.0 + make=4.3 + python=${{ matrix.python-version }} + numpy=1.26.4 + + - uses: hendrikmuhs/ccache-action@main + with: + key: ${{ github.job }}-${{ matrix.python-version }} + + - name: Show Python Info + shell: bash -e -l {0} + run: | + which python + python -m pip -V + python -m pip list + python --version + + - name: Build + shell: bash -e -l {0} + run: | + ./build0.sh + cmake . -G"Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DLPYTHON_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=no \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + + cmake --build . -j16 --target install + + - name: Test + shell: bash -e -l {0} + run: | + cd integration_tests + ./run_tests.py -b cpython c_py + + test_llvm: + name: Test LLVM ${{ matrix.llvm-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + llvm-version: ["10", "15", "16"] + steps: + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1.8.0 + with: + environment-file: ci/environment_linux_llvm.yml + create-args: >- + llvmdev=${{ matrix.llvm-version }} + + - uses: hendrikmuhs/ccache-action@main + with: + variant: sccache + key: ${{ github.job }}-${{ matrix.llvm-version }} + + - name: Build Linux + shell: bash -e -l {0} + run: | + ./build0.sh + export CXXFLAGS="-Werror" + cmake . -G"Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DLFORTRAN_BUILD_ALL=yes \ + -DWITH_STACKTRACE=no \ + -DWITH_RUNTIME_STACKTRACE=yes \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX=`pwd`/inst \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + cmake --build . -j16 --target install + + - name: Test Linux LLVM ${{ matrix.llvm-version }} + shell: bash -e -l {0} + run: | + ctest --output-on-failure + cd integration_tests + ./run_tests.py -b llvm llvm_jit + ./run_tests.py -b llvm llvm_jit -f + + build_jupyter_kernel: + name: Build Jupyter Kernel + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + jupyter=1.0.0 + python=3.10 + bison=3.4 + + - uses: hendrikmuhs/ccache-action@main + with: + variant: sccache + key: ${{ github.job }}-${{ matrix.os }} + + - name: Build LPython with Kernel + shell: bash -e -l {0} + run: | + ./build0.sh + export CXXFLAGS="-Werror" + cmake . -GNinja \ + -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_LLVM=yes \ + -DWITH_XEUS=yes \ + -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" + + ninja install + ctest --output-on-failure + jupyter kernelspec list --json + + - name: Test Kernel + shell: bash -e -l {0} + run: | + ctest --output-on-failure + + upload_tarball: + name: Upload Tarball + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Git Submodule Update + shell: bash -e -l {0} + run: | + git submodule update --init --recursive + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ci/environment.yml + create-args: >- + python=3.10 + + - name: Create Source Tarball + shell: bash -e -l {0} + run: | + ./build0.sh + lpython_version=$( version # Generate a Python AST from Python.asdl (Python) python grammar/asdl_py.py # Generate a Python AST from Python.asdl (C++) -python src/libasr/asdl_cpp.py grammar/Python.asdl src/lpython/python_ast.h +python libasr/src/libasr/asdl_cpp.py grammar/Python.asdl src/lpython/python_ast.h # Generate a Fortran ASR from ASR.asdl (C++) -python src/libasr/asdl_cpp.py src/libasr/ASR.asdl src/libasr/asr.h -# Generate a wasm_visitor.h from src/libasr/wasm_instructions.txt (C++) -python src/libasr/wasm_instructions_visitor.py +python libasr/src/libasr/asdl_cpp.py libasr/src/libasr/ASR.asdl libasr/src/libasr/asr.h +# Generate a wasm_visitor.h from libasr/src/libasr/wasm_instructions.txt (C++) +python libasr/src/libasr/wasm_instructions_visitor.py +# Generate the intrinsic_function_registry_util.h (C++) +python libasr/src/libasr/intrinsic_func_registry_util_gen.py # Generate the tokenizer and parser pushd src/lpython/parser && re2c -W -b tokenizer.re -o tokenizer.cpp && popd diff --git a/build_to_wasm.sh b/build_to_wasm.sh index 6eb3b49cf1..2d11afb250 100755 --- a/build_to_wasm.sh +++ b/build_to_wasm.sh @@ -3,9 +3,15 @@ set -e set -x +mkdir -p src/bin/asset_dir +cp src/runtime/*.py src/bin/asset_dir +cp -r src/runtime/lpython src/bin/asset_dir + +./build0.sh emcmake cmake \ - -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_FLAGS_DEBUG="-Wall -Wextra -fexceptions" \ + -DCMAKE_CXX_FLAGS_RELEASE="-Wall -Wextra -fexceptions" \ -DWITH_LLVM=no \ -DLPYTHON_BUILD_ALL=yes \ -DLPYTHON_BUILD_TO_WASM=yes \ diff --git a/ci/azure_install_macos.sh b/ci/azure_install_macos.sh deleted file mode 100755 index 5012f14ae7..0000000000 --- a/ci/azure_install_macos.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -conda config --set always_yes yes --set changeps1 no -conda info -a -conda update -q conda -conda install -c conda-forge python=3.8 re2c bison=3.4 m4 xonsh llvmdev=11.0.1 toml cmake=3.17.0 jupyter pytest xeus=1.0.1 xtl nlohmann_json cppzmq jupyter_kernel_test -export MACOSX_DEPLOYMENT_TARGET="10.12" -export CONDA_PREFIX=/usr/local/miniconda -export LFORTRAN_CMAKE_GENERATOR="Unix Makefiles" -export WIN=0 -export MACOS=1 -xonsh ci/build.xsh diff --git a/ci/build.xsh b/ci/build.xsh index fb2d9233c2..bdab77d1b9 100755 --- a/ci/build.xsh +++ b/ci/build.xsh @@ -27,19 +27,21 @@ llvm-config --components bash ci/version.sh # Generate a Fortran ASR from ASR.asdl (C++) -python src/libasr/asdl_cpp.py src/libasr/ASR.asdl src/libasr/asr.h +python libasr/src/libasr/asdl_cpp.py libasr/src/libasr/ASR.asdl libasr/src/libasr/asr.h # Generate a Python AST from Python.asdl (C++) -python src/libasr/asdl_cpp.py grammar/Python.asdl src/lpython/python_ast.h +python libasr/src/libasr/asdl_cpp.py grammar/Python.asdl src/lpython/python_ast.h # Generate a Python AST from Python.asdl (Python) python grammar/asdl_py.py -# Generate a wasm_visitor.h from src/libasr/wasm_instructions.txt (C++) -python src/libasr/wasm_instructions_visitor.py +# Generate a wasm_visitor.h from libasr/src/libasr/wasm_instructions.txt (C++) +python libasr/src/libasr/wasm_instructions_visitor.py +# Generate the intrinsic_function_registry_util.h (C++) +python libasr/src/libasr/intrinsic_func_registry_util_gen.py # Generate the tokenizer and parser pushd src/lpython/parser && re2c -W -b tokenizer.re -o tokenizer.cpp && popd pushd src/lpython/parser && bison -Wall -d -r all parser.yy && popd -$lpython_version=$(cat version).strip() +$lpython_version=$(cat lp_version).strip() $dest="lpython-" + $lpython_version bash ci/create_source_tarball0.sh tar xzf dist/lpython-$lpython_version.tar.gz diff --git a/ci/create_source_tarball.sh b/ci/create_source_tarball.sh index f1bfb4b4b7..aaf9b8e5ee 100755 --- a/ci/create_source_tarball.sh +++ b/ci/create_source_tarball.sh @@ -2,6 +2,6 @@ set -ex -lfortran_version=$1 -export dest=lfortran-$lfortran_version +lpython_version=$1 +export dest=lpython-$lpython_version bash -x -o errexit ci/create_source_tarball0.sh diff --git a/ci/create_source_tarball0.sh b/ci/create_source_tarball0.sh index bffa0f3584..ff8d6ab7db 100755 --- a/ci/create_source_tarball0.sh +++ b/ci/create_source_tarball0.sh @@ -9,9 +9,10 @@ cmake -E copy_directory src $dest/src cmake -E copy_directory share $dest/share cmake -E copy_directory cmake $dest/cmake cmake -E copy_directory examples $dest/examples +cmake -E copy_directory libasr/src/libasr $dest/libasr/src/libasr # Copy Files: -cmake -E copy CMakeLists.txt README.md LICENSE version $dest +cmake -E copy CMakeLists.txt README.md LICENSE lp_version $dest # Create the tarball cmake -E make_directory dist diff --git a/ci/environment.yml b/ci/environment.yml index b9b7fd715f..db5ded2261 100644 --- a/ci/environment.yml +++ b/ci/environment.yml @@ -4,19 +4,19 @@ channels: - defaults dependencies: - llvmdev=11.1.0 - - toml - - pytest - - jupyter - - xeus=1.0.1 - - xtl - - nlohmann_json - - cppzmq - - jupyter_kernel_test - - xonsh - - re2c - - numpy - - zlib - - ninja - - rapidjson + - toml=0.10.2 + - pytest=7.2.0 + - jupyter=1.0.0 + - xeus=5.1.0 + - xeus-zmq=3.0.0 + - nlohmann_json=3.11.3 + - jupyter_kernel_test=0.4.4 + - xonsh=0.13.3 + - re2c=2.2 + - numpy=1.26.4 + - zlib=1.3.1 + - zstd=1.5.6 + - ninja=1.11.0 + - rapidjson=1.1.0 # - bison=3.4 [not win] # - m2-bison=3.4 [win] diff --git a/ci/environment_linux_llvm.yml b/ci/environment_linux_llvm.yml new file mode 100644 index 0000000000..ffe4ddd2a9 --- /dev/null +++ b/ci/environment_linux_llvm.yml @@ -0,0 +1,20 @@ +name: lp +channels: + - conda-forge + - defaults +dependencies: + - git + - pip + - make + - re2c + - toml + - zlib + - cmake + - numpy + - flake8 + - setuptools + - bison=3.4 + - python=3.10.2 + - zstd-static=1.5 + - symengine=0.12.0 + - sympy=1.11.1 diff --git a/ci/test.xsh b/ci/test.xsh index 50622fd55f..23285e1ed9 100644 --- a/ci/test.xsh +++ b/ci/test.xsh @@ -13,14 +13,21 @@ src/bin/lpython -o expr2 expr2.o # Test the new Python frontend, manually for now: src/bin/lpython --show-ast tests/doconcurrentloop_01.py src/bin/lpython --show-asr tests/doconcurrentloop_01.py -src/bin/lpython --show-cpp tests/doconcurrentloop_01.py +# src/bin/lpython --show-cpp tests/doconcurrentloop_01.py if $WIN == "1": python run_tests.py --skip-run-with-dbg --no-color else: python run_tests.py + src/bin/lpython examples/expr2.py + src/bin/lpython --backend=c examples/expr2.py cd integration_tests - python run_tests.py -j16 -b llvm cpython c wasm if $(uname).strip() == "Linux": + python run_tests.py -j16 -b llvm cpython c wasm + python run_tests.py -j16 -b llvm cpython c wasm -f python run_tests.py -j16 -b x86 wasm_x86 wasm_x64 + python run_tests.py -j16 -b x86 wasm_x86 wasm_x64 -f + else: + python run_tests.py -j1 -b llvm cpython c wasm + python run_tests.py -j1 -b llvm cpython c wasm -f diff --git a/ci/upload_tarball_to_release.sh b/ci/upload_tarball_to_release.sh new file mode 100755 index 0000000000..cc8f1e1c32 --- /dev/null +++ b/ci/upload_tarball_to_release.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -ex + +lpython_version=$( version +echo $version > lp_version diff --git a/cmake/UserOverride.cmake b/cmake/UserOverride.cmake index 3139f24c87..5c50301187 100644 --- a/cmake/UserOverride.cmake +++ b/cmake/UserOverride.cmake @@ -9,7 +9,12 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # g++ set(common "-Wall -Wextra") - set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -march=native -funroll-loops -DNDEBUG") + if (CMAKE_SYSTEM_PROCESSOR MATCHES "ppc|powerpc") + set(native "-mtune=native") + else () + set(native "-march=native") + endif () + set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 ${native} -funroll-loops -DNDEBUG") set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # icpc diff --git a/doc/src/asr/asr_nodes/expression_nodes/IntrinsicFunction.md b/doc/src/asr/asr_nodes/expression_nodes/IntrinsicFunction.md new file mode 100644 index 0000000000..f5c53c6c7b --- /dev/null +++ b/doc/src/asr/asr_nodes/expression_nodes/IntrinsicFunction.md @@ -0,0 +1,107 @@ +# IntrinsicFunction + +An intrinsic function. An **expr** node. + +## Declaration + +### Syntax + +``` +IntrinsicFunction(expr* args, int intrinsic_id, int overload_id, + ttype type, expr? value) +``` + +### Arguments + +* `args` represents all arguments passed to the function +* `intrinsic_id` is the unique ID of the generic intrinsic function +* `overload_id` is the ID of the signature within the given generic function +* `type` represents the type of the output +* `value` is an optional compile time value + +### Return values + +The return value is the expression that the `IntrinsicFunction` represents. + +## Description + +**IntrinsicFunction** represents an intrinsic function (such as `Abs`, +`Modulo`, `Sin`, `Cos`, `LegendreP`, `FlipSign`, ...) that either the backend +or the middle-end (optimizer) needs to have some special logic for. Typically a +math function, but does not have to be. + +IntrinsicFunction is both side-effect-free (no writes to global variables) and +deterministic (no reads from global variables). They are also elemental: can be +vectorized over any argument(s). They can be used inside parallel code and +cached. + +The `intrinsic_id` determines the generic function uniquely (`Sin` and `Abs` +have different number, but `IntegerAbs` and `RealAbs` share the number) and +`overload_id` uniquely determines the signature starting from 0 for each +generic function (e.g., `IntegerAbs`, `RealAbs` and `ComplexAbs` can have +`overload_id` equal to 0, 1 and 2, and `RealSin`, `ComplexSin` can be 0, 1). + +Backend use cases: Some architectures have special hardware instructions for +operations like Sqrt or Sin and if they are faster than a software +implementation, the backend will use it. This includes the `FlipSign` function +which is our own "special function" that the optimizer emits for certain +conditional floating point operations, and the backend emits an efficient bit +manipulation implementation for architectures that support it. + +Middle-end use cases: the middle-end can use the high level semantics to +simplify, such as `sin(e)**2 + cos(e)**2 -> 1`, or it could approximate +expressions like `if (abs(sin(x) - 0.5) < 0.3)` with a lower accuracy version +of `sin`. + +We provide ASR -> ASR lowering transformations that substitute the given +intrinsic function with an ASR implementation using more primitive ASR nodes, +typically implemented in the surface language (say a `sin` implementation using +argument reduction and a polynomial fit, or a `sqrt` implementation using a +general power formula `x**(0.5)`, or `LegendreP(2,x)` implementation using a +formula `(3*x**2-1)/2`). + +This design also makes it possible to allow selecting using command line +options how certain intrinsic functions should be implemented, for example if +trigonometric functions should be implemented using our own fast +implementation, `libm` accurate implementation, we could also call into other +libraries. These choices should happen at the ASR level, and then the result +further optimized (such as inlined) as needed. + +## Types + +The argument types in `args` have the types of the corresponding signature as +determined by `intrinsic_id`. For example `IntegerAbs` accepts an integer, but +`RealAbs` accepts a real. + +## Examples + +The following example code creates `IntrinsicFunction` ASR node: + +```fortran +sin(0.5) +``` + +ASR: + +``` +(TranslationUnit + (SymbolTable + 1 + { + }) + [(IntrinsicFunction + [(RealConstant + 0.500000 + (Real 4 []) + )] + 0 + 0 + (Real 4 []) + (RealConstant 0.479426 (Real 4 [])) + )] +) +``` + +## See Also + +[FunctionCall]() \ No newline at end of file diff --git a/doc/src/built-in functions.md b/doc/src/built-in functions.md new file mode 100644 index 0000000000..b9804b5c28 --- /dev/null +++ b/doc/src/built-in functions.md @@ -0,0 +1,147 @@ +# Built-in Functions + +LPython has a variety of functions and types built into it that are always available. + +### abs(x) + +- **Parameter** + - x : integer (i8, i16, i32, i64), floating point number (f32, f64), complex number (c32, c64) or bool +- **Returns** : integer (i8, i16, i32, i64), floating point number (f32, f64) + +Returns the absolute value of a number. If the argument is a complex number, its magnitude is returned. + + +### bin(n) + +- **Parameters** + - n : integer (i32) +- **Returns** : str + +Returns the binary representation of n as a '0b' prefixed string. + + +### complex(x=0, y=0) + +- **Parameters** + - x : integer (i32, i64) or floating point number (f32, f64) + - y : integer (i32, i64) or floating point number (f32, f64) +- **Returns** : complex number (c32, c64) + +Returns a complex number with the provided real and imaginary parts. Both x and y should be of the same type. However, using both the 32-bit and 64-bit versions of the same type together is allowed. In that case, the returned complex number is of 64-bit type. + +Example: + +```python +real: i32 = 10 +imag: i64 = 22 +c: c64 = complex(real, imag) +``` + +### divmod(x, y) + +- **Parameters** + - x : integer (i32) + - y : integer (i32) +- **Returns** : tuple[i32, i32] + +Returns the tuple (x // y, x % y). + + +### exp(x) + +- ****Parameter**** + - x : floating point number (f32, f64) +- **Returns** : floating point number (f32, f64) between [0.0, inf] + +Returns the base-e exponential of x (ex), where e is the Euler's number (2.71828). For a very large output, the function returns **inf** indicating overflow. + + +### hex(n) + +- **Parameters** + - n : integer (i32) +- **Returns** : str + +Returns the hexadecimal representation of n as a '0x' prefixed string. + + +### len(s) + +- **Parameters** + - s : sequence (such as string, tuple, list or range) or collection (such as a dictionary or set) +- **Returns** : integer (i32) + +Returns the number of items present in an object. + + +### max(x, y) + +- **Parameters** + - x : integer (i32) or floating point number (f64) + - y : integer (i32) or floating point number (f64) +- **Returns** : integer (i32) or floating point number (f64) + +Returns the greater value between x and y. Both x and y should be of the same type. + + +### min(x, y) + +- **Parameters** + - x : integer (i32) or floating point number (f64) + - y : integer (i32) or floating point number (f64) +- **Returns** : integer (i32) or floating point number (f64) + +Returns the smaller value between x and y. Both x and y should be of the same type. + + +### mod(x, y) + +- **Parameters** + - x : integer (i32, i64) or floating point number (f32, f64) + - y : integer (i32, i64) or floating point number (f32, f64) +- **Returns** : integer (i32, i64) or floating point number (f32, f64) + +Returns the remainder of x / y, or x when x is smaller than y. Both x and y should be of the same type. + + +### pow(x, y) + +- **Parameters** + - x : integer (i32, i64), floating point number (f32, f64), complex number (c32) or bool + - y: integer (i32, i64), floating point number (f32, f64) or bool +- **Returns** : integer (i32), floating point number (f32, f64) or a complex number + +Returns xy. When x is of type bool, y must also be of the same type. If x is 32-bit complex number (c32), y can only be a 32-bit integer (i32). + +**Note** : `x ** y` is the recommended method for doing the above calculation. + + +### round(x) + +- **Parameters** + - x : integer (i8, i16, i32, i64), floating point number (f32, f64) or bool +- **Returns** : integer (i8, i16, i32, i64) + +Returns the integer nearest to x. + + +### sum(arr) + +- **Parameters** + - arr : list of integers (list[i32], list[i64]) or floating point numbers (list[i32], list[f64]) +- **Returns** : integer (i32, i64) or floating point number (f32, f64) + +Returns the sum of all elements present in the list. + + +### oct(n) + +- **Parameters** + - n : integer (i32) +- **Returns** : str + +Returns the octal representation of n as a '0o' prefixed string. + + + + diff --git a/doc/src/design.md b/doc/src/design.md index d7510e6c29..d477039a0b 100644 --- a/doc/src/design.md +++ b/doc/src/design.md @@ -91,7 +91,7 @@ ASR is the simplest way to generate Fortran code, as one does not have to worry about the detailed syntax (as in AST) about how and where things are declared. One specifies the symbol table for a module, then for each symbol (functions, global variables, types, ...) one specifies the local -variables and if this is an interface then one needs to specify where one can +variables and if this is an interface then one must specify where one can find an implementation, otherwise a body is supplied with statements, those nodes are almost the same as in AST, except that each variable is just a reference to a symbol in the symbol table (so by construction one cannot have diff --git a/doc/src/developers_example.ipynb b/doc/src/developers_example.ipynb new file mode 100644 index 0000000000..c63754c8f0 --- /dev/null +++ b/doc/src/developers_example.ipynb @@ -0,0 +1,67 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "c86338ac-53ca-4115-8c5a-8bf8a5c7113e", + "metadata": {}, + "outputs": [], + "source": [ + "%%showast\n", + "def add(x: i32, y: i32) -> i32:\n", + " return x + y" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23834b08-2f3f-45e7-a1ce-21a9fd4e5117", + "metadata": {}, + "outputs": [], + "source": [ + "%%showasr\n", + "def add(x: i32, y: i32) -> i32:\n", + " return x + y" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec7426b4-e2e5-416c-bcae-9bb9c8926c9b", + "metadata": {}, + "outputs": [], + "source": [ + "%%showllvm\n", + "def sub(x: i32, y: i32) -> i32:\n", + " return add(x, -y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "716c56ef-8210-4daf-aa23-96b385801014", + "metadata": {}, + "outputs": [], + "source": [ + "%%showasm\n", + "def mul(x: i32, y: i32) -> i32:\n", + " return x * y" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "LPython", + "language": "python", + "name": "lpython" + }, + "language_info": { + "file_extension": ".f90", + "mimetype": "text/x-python", + "name": "python", + "version": "2018" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/src/installation.md b/doc/src/installation.md index af9e91fe83..a6bdd9250e 100644 --- a/doc/src/installation.md +++ b/doc/src/installation.md @@ -1,146 +1,210 @@ # Installation -All the instructions below work on Linux, macOS and Windows. +Follow the steps below to install and run LPython on Linux, Windows or macOS. + +## Prerequisites +- ### Install Conda + Follow the instructions provided [here](https://github.com/conda-forge/miniforge/#download) to install Conda on your platform (Linux, macOS and Windows) using a conda-forge distribution called Miniforge. + + For Windows, these are additional requirements: + - Miniforge Prompt + - Visual Studio (with "Desktop Development with C++" workload) + +- ### Set up your system + - Linux + - Run the following command to install some global build dependencies: + + ```bash + sudo apt-get install build-essential binutils-dev clang zlib1g-dev + ``` + - Windows + - Download and install [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/downloads/) for free. + + - Run the Visual Studio Installer. Download and install the "Desktop Development with C++" workload which will install the Visual C++ Compiler (MSVC). + + - Launch the Miniforge prompt from the Desktop. It is recommended to use MiniForge instead of Powershell as the main terminal to build and write code for LPython. In the MiniForge Prompt, initialize the MSVC compiler using the below command: + + ```bash + call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd" -arch=x64 + ``` + + You can optionally test MSVC via: + + ```bash + cl /? + link /? + ``` + + Both commands must print several pages of help text. + + - Windows with WSL + - Install Miniforge Prompt and add it to path: + ```bash + wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniconda.sh + bash miniconda.sh -b -p $HOME/conda_root + export PATH="$HOME/conda_root/bin:$PATH" + conda init bash # (shell name) + ``` + - Open a new terminal window and run the following commands to install dependencies: + ```bash + conda create -n lp -c conda-forge llvmdev=11.0.1 bison=3.4 re2c python cmake make toml clangdev git + ``` + + - Optionally, you can change the directory to a Windows location using `cd /mnt/[drive letter]/[windows location]`. For e.g. - `cd mnt/c/Users/name/source/repos/`. + + +- ### Clone the LPython repository + Make sure you have `git` installed. Type the following command to clone the repository: + + ```bash + git clone https://github.com/lcompilers/lpython.git + cd lpython + git submodule update --init + ``` + + You may also use GitHub Desktop to do the same. + +## Building LPython +- ### Linux and macOS + - Create a Conda environment: + + ```bash + conda env create -f environment_unix.yml + conda activate lp + ``` -## Binaries + - Generate the prerequisite files and build in Debug Mode: -The recommended way to install LFortran is using Conda. -Install Conda for example by installing the -[Miniconda](https://conda.io/en/latest/miniconda.html) installation by following instructions there for your platform. -Then create a new environment (you can choose any name, here we chose `lf`) and -activate it: -```bash -conda create -n lp -conda activate lp -``` -Then install LFortran by: -```bash -conda install lfortran -c conda-forge -``` -Now the `lf` environment has the `lfortran` compiler available, you can start the -interactive prompt by executing `lfortran`, or see the command line options using -`lfortran -h`. + ```bash + # if you are developing on top of a forked repository; please run following command first + # ./generate_default_tag.sh -The Jupyter kernel is automatically installed by the above command, so after installing Jupyter itself: -```bash -conda install jupyter -c conda-forge -``` -You can create a Fortran based Jupyter notebook by executing: -```bash -jupyter notebook -``` -and selecting `New->Fortran`. + ./build0.sh + ./build1.sh + ``` + +- ### Windows + - Create a Conda environment using the pre-existing file: -## Build From a Source Tarball + ```bash + conda env create -f environment_win.yml + conda activate lp + ``` -This method is the recommended method if you just want to install LFortran, either yourself or in a package manager (Spack, Conda, Debian, etc.). The source tarball has all the generated files included and has minimal dependencies. + - Generate the prerequisite files and build in Release Mode: -First we have to install dependencies, for example using Conda: -```bash -conda create -n lf python cmake llvmdev -conda activate lf -``` -Then download a tarball from -[https://lfortran.org/download/](https://lfortran.org/download/), -e.g.: -```bash -wget https://lfortran.github.io/tarballs/dev/lfortran-0.9.0.tar.gz -tar xzf lfortran-0.9.0.tar.gz -cd lfortran-0.9.0 -``` -And build: -``` -cmake -DWITH_LLVM=yes -DCMAKE_INSTALL_PREFIX=`pwd`/inst . -make -j8 -make install -``` -This will install the `lfortran` into the `inst/bin`. + ```bash + call build0.bat + call build1.bat + ``` +- ### Windows with WSL -## Build From Git + - Activate the Conda environment: + ```bash + conda activate lp + ``` -We assume you have C++ compilers installed, as well as `git` and `wget`. -In Ubuntu, you can also install `binutils-dev` for stacktraces. + - Run the following commands to build the project: + ```bash + ./build0.sh + cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_LLVM=yes -DCMAKE_INSTALL_PREFIX=`pwd`/inst .\ + make -j8 + ``` -If you do not have Conda installed, you can do so on Linux (and similarly on -other platforms): -```bash -wget --no-check-certificate https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh -bash miniconda.sh -b -p $HOME/conda_root -export PATH="$HOME/conda_root/bin:$PATH" -``` -Then prepare the environment: -```bash -conda create -n lp -c conda-forge llvmdev=11.0.1 bison=3.4 re2c python cmake make toml numpy -conda activate lp -``` -Clone the LFortran git repository: -``` -git clone https://gitlab.com/lfortran/lfortran.git -cd lfortran -``` -Generate files that are needed for the build (this step depends on `re2c`, `bison` and `python`): -```bash -./build0.sh -``` -Now the process is the same as installing from the source tarball. For example to build in Debug mode: -``` -cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_LLVM=yes -DCMAKE_INSTALL_PREFIX=`pwd`/inst . -make -j8 -``` +## Tests -Run tests: -```bash -ctest -./run_tests.py -``` -Run an interactive prompt: -```bash -./src/bin/lfortran -``` +- ### Linux and macOS -## Build on Windows with Visual Studio + - Run tests: -Install Conda for example by installing the Miniconda installation by following instructions there for your platform. If not already done, activate the Conda-Installation (cf. Conda installation instructions). + ```bash + ctest + ./run_tests.py + ``` -First, clone the repo to a local folder. + - Update test references: + ``` + ./run_tests.py -u + ``` -Launch a Conda command interpreter and run the following commands: -```bash -conda update -q conda -conda install -c conda-forge python=3.7 re2c m2-bison xonsh llvmdev=11.1.0 jupyter xeus=1.0.1 xtl nlohmann_json cppzmq jupyter_kernel_test pytest -``` -Next, `cd` to the root of the repository and run -```bash -.\build0.bat -``` + - Run integration tests: + + ```bash + cd integration_tests + ./run_tests.py + ``` + - In case you have recently updated macOS, you may get a warning like below in some test cases: + ```bash + ld: warning: object file (test_list_index2.out.tmp.o) was built for newer macOS version (14.0) than being linked (13.3) + ``` + This leads to mismatch of hashes with expected output in some test cases, this can be resolved by updating command line tools: + + ```bash + git clean -dfx + sudo rm -rf /Library/Developer/CommandLineTools # make sure you know what you're doing here + sudo xcode-select --install + ./build.sh + ./run_tests.py + ``` + + - Speed up Integration Tests on macOS + + Integration tests run slowly because Apple checks the hash of each + executable online before running. + + You can turn off that feature in the Privacy tab of the Security and Privacy item of System Preferences > Developer Tools > Terminal.app > "allow the apps below to run software locally that does not meet the system's security + policy." + + +- ### Windows + + - Run integration tests + + ```bash + python run_tests.py --skip-run-with-dbg + ``` -Now, you can launch Visual Studio and open the LFortran folder. -Before the first build you have to set up the `ZLib`-pathes: Go to the CMake-Settings (Project -> CMake Settings for lfortran) and check `Show advanced variables`. Scroll to the `ZLIB_...` variables and set: -- `ZLIB_INCLUDE_DIR` = \\Library\include -- `ZLIB_LIBRARY_[DEBUG|RELEASE]` = \\Library\lib\zlib.lib + - Update reference tests -Then you can generate the CMake-Cache and build the project. + ```bash + python run_tests.py -u --skip-run-with-dbg + ``` + +## Examples (Linux and macOS) + +You can run the following examples manually in a terminal: + +```bash +./src/bin/lpython examples/expr2.py +./src/bin/lpython examples/expr2.py -o expr +./expr +./src/bin/lpython --show-ast examples/expr2.py +./src/bin/lpython --show-asr examples/expr2.py +./src/bin/lpython --show-cpp examples/expr2.py +./src/bin/lpython --show-llvm examples/expr2.py +./src/bin/lpython --show-c examples/expr2.py +``` ## Enabling the Jupyter Kernel To install the Jupyter kernel, install the following Conda packages also: ``` -conda install xeus xtl nlohmann_json cppzmq +conda install xeus=5.1.0 xeus-zmq=3.0.0 nlohmann_json ``` and enable the kernel by `-DWITH_XEUS=yes` and install into `$CONDA_PREFIX`. For example: ``` -cmake \ +cmake . -GNinja \ -DCMAKE_BUILD_TYPE=Debug \ -DWITH_LLVM=yes \ -DWITH_XEUS=yes \ -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \ - -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" \ + -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" . -cmake --build . -j4 --target install +ninja install ``` -To use it, install Jupyter (`conda install jupyter`) and test that the LFortran +To use it, install Jupyter (`conda install jupyter`) and test that the LPython kernel was found: ``` jupyter kernelspec list --json @@ -149,111 +213,14 @@ Then launch a Jupyter notebook as follows: ``` jupyter notebook ``` -Click `New->Fortran`. To launch a terminal jupyter LFortran console: -``` -jupyter console --kernel=fortran -``` - - -## Build From Git with Nix - -One of the ways to ensure exact environment and dependencies is with `nix`. This will ensure that system dependencies do not interfere with the development environment. If you want, you can report bugs in a `nix-shell` environment to make it easier for others to reproduce. - -### With Root - -We start by getting `nix`. The following multi-user installation will work on any machine with a Linux distribution, MacOS or Windows (via WSL): -```bash -sh <(curl -L https://nixos.org/nix/install) --daemon -``` -### Without Root - -If you would like to not provide `nix` with root access to your machine, on Linux distributions we can use [nix-portable](https://github.com/DavHau/nix-portable). -```bash -wget https://github.com/DavHau/nix-portable/releases/download/v003/nix-portable -``` -Now just prepend all `nix-shell` commands with `NP_RUNTIME=bwrap ./nix-portable `. So: -```bash -# Do not -nix-shell --run "bash" -# Do -NP_RUNTIME=bwrap ./nix-portable nix-shell --run "bash" -``` - -### Development - -Now we can enter the development environment: -```bash -nix-shell --run "bash" --cores 4 -j4 --pure ci/shell.nix -``` -The `--pure` flag ensures no system dependencies are used in the environment. - -The build steps are the same as with the `ci`: -```bash -./build0.sh -./build1.sh +Click `New->LPython`. To launch a terminal jupyter LPython console: ``` - -To change the compilation environment from `gcc` (default) to `clang` we can use `--argstr`: -```bash -nix-shell --run "bash" --cores 4 -j4 --pure ci/shell.nix --argstr clangOnly "yes" +jupyter console --kernel=lpython ``` -## Note About Dependencies - -End users (and distributions) are encouraged to use the tarball -from [https://lfortran.org/download/](https://lfortran.org/download/), -which only depends on LLVM, CMake and a C++ compiler. - -The tarball is generated automatically by our CI (continuous integration) and -contains some autogenerated files: the parser, the AST and ASR nodes, which is generated by an ASDL -translator (requires Python). - -The instructions from git are to be used when developing LFortran itself. - -## Note for users who do not use Conda - -Following are the dependencies necessary for installing this -repository in development mode, +## Found a bug? +Please report any bugs you find at our issue tracker [here](https://github.com/lcompilers/lpython/issues). Or, even better, fork the repository on GitHub and create a Pull Request (PR). -- [Bison - 3.5.1](https://ftp.gnu.org/gnu/bison/bison-3.5.1.tar.xz) -- [LLVM - 11.0.1](https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.1/llvm-11.0.1.src.tar.xz) -- [re2c - 2.0.3](https://re2c.org/install/install.html) -- [binutils - 2.31.90](ftp://sourceware.org/pub/binutils/snapshots/binutils-2.31.90.tar.xz) - Make sure that you should enable the required options related to this dependency to build the dynamic libraries (the ones ending with `.so`). +We welcome all changes, big or small. We will help you make a PR if you are new to git. -## Stacktraces - -LFortran can print stacktraces when there is an unhandled exception, as well as -on any compiler error with the `--show-stacktrace` option. This is very helpful -for developing the compiler itself to see where in LFortran the problem is. The -stacktrace support is turned off by default, to enable it, -compile LFortran with the `-DWITH_STACKTRACE=yes` cmake option after installing -the prerequisites on each platform per the instructions below. - -### Ubuntu - -In Ubuntu, `apt install binutils-dev`. - -### macOS - -If you use the default Clang compiler on macOS, then the stacktraces should -just work on both Intel and M1 based macOS (the CMake build system -automatically invokes the `dsymtuil` tool and our Python scripts to store the -debug information, see `src/bin/CMakeLists.txt` for more details). If it does -not work, please report a bug. - -If you do not like the default way, an alternative is to use bintutils. For -that, first install -[Spack](https://spack.io/), then: -``` -spack install binutils -spack find -p binutils -``` -The last command will show a full path to the installed `binutils` package. Add -this path to your shell config file, e.g.: -``` -export CMAKE_PREFIX_PATH_LFORTRAN=/Users/ondrej/repos/spack/opt/spack/darwin-catalina-broadwell/apple-clang-11.0.0/binutils-2.36.1-wy6osfm6bp2323g3jpv2sjuttthwx3gd -``` -and compile LFortran with the -`-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH_LFORTRAN;$CONDA_PREFIX"` cmake option. -The `$CONDA_PREFIX` is there if you install some other dependencies (such as -`llvm`) using Conda, otherwise you can remove it. +If you have any questions or need help, please ask us at [Zulip](https://lfortran.zulipchat.com/) or on our [mailinglist](https://groups.io/g/lfortran). diff --git a/doc/src/rebasing.md b/doc/src/rebasing.md index 1c5581b6e3..26cefa3355 100644 --- a/doc/src/rebasing.md +++ b/doc/src/rebasing.md @@ -1,5 +1,5 @@ -You should clean your branch's commits, and we have two approach for this. +You should clean your branch's commits, and we have two approaches for this. # Rebasing ```bash @@ -56,9 +56,9 @@ Date: Sat Jul 30 15:46:28 2022 +0530 Implementing tuples in LLVM backend ``` -here, we want make our commits as a bunch of batches. +here, we want to make our commits as a bunch of batches. -we will rebasing with main with interactive option `git rebase main -i`. +we will rebase with main with the interactive option `git rebase main -i`. but first create a backup branch before doing this interactive rebase. @@ -111,8 +111,8 @@ s 122a02bf3 refactor s 663edf45b refactor ... ``` -and it will open windows for every change you made to rename commit's message. -- first window to rename commit `Added add3.py` because we squashed the commit after it, and by default the message would be the original message of `Added add3.py` and messages of squashed commits, here i will not change anything i will leave message like that. +and it will open windows for every change you made to rename the commit's message. +- first window to rename commit `Added add3.py` because we squashed the commit after it, and by default the message would be the original message of `Added add3.py` and messages of squashed commits, here I will not change anything I will leave message like that. ```bash # This is a combination of 2 commits. # This is the 1st commit message: @@ -143,7 +143,7 @@ Refactor # Untracked files: ... ``` -- second window: rename(rewword) `Added add4.py`, you can edit the message as you want, i will rename it: `Added add4.py and edit it ` . +- second window: rename(reword) `Added add4.py`, you can edit the message as you want, I will rename it: `Added add4.py and edit it ` . ``` Added add4.py @@ -187,7 +187,7 @@ Added add4.py and edit it # with '#' will be ignored, and an empty message aborts the commit. ... ``` -- third window will be the same as dirst one because of squashing two commits to commit:`Added add4.py`, i will leave it with out changing message. +- third window will be the same as the first one because of squashing two commits to commit:`Added add4.py`, I will leave it without changing the message. Log now: ```bash @@ -223,7 +223,7 @@ Date: Sat Jul 30 23:36:27 2022 +0200 Added add.py ``` -and if you want to push to remote branch you must push with `--force` option. +and if you want to push to the remote branch you must push with `--force` option. This [video](https://drive.google.com/file/d/1506h86_RLgwtjLi_uKWbdVNDsSVusIbr/view?usp=sharing) by *Naman Gera* he was rebasing a branch. @@ -232,7 +232,7 @@ This [video](https://drive.google.com/file/d/1506h86_RLgwtjLi_uKWbdVNDsSVusIbr/v # Merging by *Gagandeep Singh* from [#783 comment](https://github.com/lcompilers/lpython/pull/783#issuecomment-1188875210) -Assuming initial state is your current branch (say `xyz_branch`), +Assuming the initial state is your current branch (say `xyz_branch`), 1. git checkout main or git checkout master (whichever is being used in a certain project as the lead branch). 2. git pull origin main (origin is the project remote say for lpython it will be pointing to (https://github.com/lcompilers/lpython). @@ -243,4 +243,4 @@ Assuming initial state is your current branch (say `xyz_branch`), 7. Repeat step 6 until you are satisfied with the group of changes you want to commit. 8. `git commit -m "nice_commit_message"` or `git commit (and then write detailed commit message in the command line editor)`. 9. Repeat 7 and 8 until all the changes are committed. -10. `git push -f your_remote xyz_branch`. \ No newline at end of file +10. `git push -f your_remote xyz_branch`. diff --git a/environment_unix.yml b/environment_unix.yml index 0942bbcbaf..af7dffcff0 100644 --- a/environment_unix.yml +++ b/environment_unix.yml @@ -2,16 +2,17 @@ name: lp channels: - conda-forge dependencies: - - bison=3.4 - - cmake - - flake8 - - llvmdev=11.0.1 - - make - - numpy + - git - pip - - python=3.10.2 + - make - re2c - - setuptools - toml - zlib - - git + - cmake + - numpy + - flake8 + - setuptools + - bison=3.4 + - python=3.10.2 + - llvmdev=11.0.1 + - zstd-static=1.5.5 diff --git a/environment_win.yml b/environment_win.yml index af80e30c7c..60774b822c 100644 --- a/environment_win.yml +++ b/environment_win.yml @@ -2,18 +2,19 @@ name: lp channels: - conda-forge dependencies: - - python=3.10.2 - - numpy - - flake8 + - git - pip + - make + - re2c - toml + - zlib + - cmake + - ninja + - numpy + - xonsh + - flake8 - setuptools - - llvmdev=11.1.0 + - python=3.10.2 - m2-bison=3.0.4 - - re2c - - xonsh - - ninja - - cmake - - make - - zlib - - git + - llvmdev=11.1.0 + - zstd-static=1.5.5 diff --git a/examples/example_notebook.ipynb b/examples/example_notebook.ipynb new file mode 100644 index 0000000000..17ce1ba2db --- /dev/null +++ b/examples/example_notebook.ipynb @@ -0,0 +1,134 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "e87300c2-64ed-4636-8448-591f36faba29", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, LPython\n" + ] + } + ], + "source": [ + "print(\"Hello, LPython\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "dfcac851-7b49-4065-8c64-4a31658249f7", + "metadata": {}, + "outputs": [], + "source": [ + "def add(x: i32, y: i32) -> i32:\n", + " return x + y" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "09213386-84d5-4e7c-83ba-c3b027f765dd", + "metadata": {}, + "outputs": [], + "source": [ + "def sub(x: i32, y: i32) -> i32:\n", + " return x - y" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a4b49fd3-bf17-4287-9d5e-60f14ebc9a0f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "add(2, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d6f4961f-7f0c-45a6-9bf8-e549e97098b0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sub(2, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "398fd4be-d7cc-4912-8aa1-880aa58b37ab", + "metadata": {}, + "outputs": [], + "source": [ + "@dataclass\n", + "class MyClass:\n", + " x: i32\n", + " y: f64\n", + " z: str" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "628f0b7d-09a6-49de-a0e6-2f6c664f2ba2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12 2.45000000000000000e+01 LPython\n" + ] + } + ], + "source": [ + "x: MyClass = MyClass(12, 24.5, \"LPython\")\n", + "print(x)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "LPython", + "language": "python", + "name": "lpython" + }, + "language_info": { + "file_extension": ".f90", + "mimetype": "text/x-python", + "name": "python", + "version": "2018" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/expr2.py b/examples/expr2.py index 2e66f1e584..484873ac2d 100644 --- a/examples/expr2.py +++ b/examples/expr2.py @@ -1,10 +1,9 @@ +from lpython import i32 + def main0(): x: i32 x = (2+3)*5 print(x) -main0() - -# Not implemented yet in LPython: -#if __name__ == "__main__": -# main() +if __name__ == "__main__": + main0() diff --git a/generate_default_tag.sh b/generate_default_tag.sh new file mode 100755 index 0000000000..b38b4d7239 --- /dev/null +++ b/generate_default_tag.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# Run this script when your local repo +# #doesn't automatically fetch tags from upstream +# It allows local development with a mocked tag +echo "Generating default tag..." +set -ex +git tag "v0.0.0=0" diff --git a/grammar/Python.asdl b/grammar/Python.asdl index a5ca1c672e..ade97a49a0 100644 --- a/grammar/Python.asdl +++ b/grammar/Python.asdl @@ -73,6 +73,7 @@ module LPython -- need sequences for compare to distinguish between -- x < 4 < 3 and (x < 4) < 3 | Compare(expr left, cmpop ops, expr* comparators) + | Membership(expr left, membershipop op, expr right) | Call(expr func, expr* args, keyword* keywords) | FormattedValue(expr value, int conversion, expr? format_spec) | JoinedStr(expr* values) @@ -110,7 +111,9 @@ module LPython unaryop = Invert | Not | UAdd | USub - cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn + cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot + + membershipop = In | NotIn comprehension = (expr target, expr iter, expr* ifs, int is_async) diff --git a/grammar/asdl_py.py b/grammar/asdl_py.py index 1e3844131e..bb897b300d 100644 --- a/grammar/asdl_py.py +++ b/grammar/asdl_py.py @@ -5,7 +5,7 @@ import sys import os -sys.path.append("src/libasr") +sys.path.append("libasr/src/libasr") import asdl products = [] diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 737e3a52f3..e81feb9db2 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(lpython_tests C) @@ -13,11 +13,23 @@ if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR endif () set(KIND no CACHE STRING "Type of Test") +set(FAST no CACHE BOOL "Run supported tests with --fast") + +find_program(LPYTHON NAMES lpython) + +execute_process(COMMAND ${LPYTHON} --get-rtl-header-dir + OUTPUT_VARIABLE LPYTHON_RTL_HEADER_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +execute_process(COMMAND ${LPYTHON} --get-rtl-dir + OUTPUT_VARIABLE LPYTHON_RTL_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) find_path(LPYTHON_RTLIB_DIR lfortran_intrinsics.h - ${CMAKE_SOURCE_DIR}/../src/libasr/runtime) + HINTS ${LPYTHON_RTL_HEADER_DIR}) find_library(LPYTHON_RTLIB_LIBRARY lpython_runtime_static - ${CMAKE_SOURCE_DIR}/../src/runtime/) + HINTS ${LPYTHON_RTL_DIR}) add_library(lpython_rtlib INTERFACE IMPORTED) set_property(TARGET lpython_rtlib PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LPYTHON_RTLIB_DIR}) @@ -25,6 +37,24 @@ set_property(TARGET lpython_rtlib PROPERTY INTERFACE_LINK_LIBRARIES ${LPYTHON_RTLIB_LIBRARY}) target_link_libraries(lpython_rtlib INTERFACE m) +if (PYTHON_LIBS_REQ) + find_package(Python COMPONENTS Interpreter Development) + execute_process( + COMMAND "${Python_EXECUTABLE}" + -c "import numpy; print(numpy.get_include())" + OUTPUT_VARIABLE NUMPY_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message("\n") + message("System has the Python development artifacts: ${Python_Development_FOUND}") + message("The Python include directories: ${Python_INCLUDE_DIRS}") + message("The Python libraries: ${Python_LIBRARIES}") + message("The Python library directories: ${Python_LIBRARY_DIRS}") + message("The Python runtime library directories: ${Python_RUNTIME_LIBRARY_DIRS}") + message("Python version: ${Python_VERSION}") + message("Numpy Include Directory: ${NUMPY_INCLUDE_DIR}") +endif() + enable_testing() message("\n") @@ -39,160 +69,342 @@ else () endif () message("Installation prefix: ${CMAKE_INSTALL_PREFIX}") message("KIND: ${KIND}") +message("FAST: ${FAST}") +message("PYTHON_LIBS_REQ: ${PYTHON_LIBS_REQ}") +message("LPYTHON: ${LPYTHON}") message("LPYTHON_RTLIB_DIR: ${LPYTHON_RTLIB_DIR}") message("LPYTHON_RTLIB_LIBRARY: ${LPYTHON_RTLIB_LIBRARY}") +macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_NOMOD RUN_EXTRA_ARGS RUN_COPY_TO_BIN) + set(fail ${${RUN_FAIL}}) + set(name ${${RUN_NAME}}) + set(file_name ${${RUN_FILE_NAME}}) + set(labels ${${RUN_LABELS}}) + set(extra_files ${${RUN_EXTRAFILES}}) + set(no_mod ${${RUN_NOMOD}}) + set(extra_args ${${RUN_EXTRA_ARGS}}) + set(copy_to_bin ${${RUN_COPY_TO_BIN}}) -macro(RUN) - set(options FAIL) - set(oneValueArgs NAME IMPORT_PATH) - set(multiValueArgs LABELS EXTRAFILES) - cmake_parse_arguments(RUN "${options}" "${oneValueArgs}" - "${multiValueArgs}" ${ARGN} ) - set(name ${RUN_NAME}) - set(import_path ${RUN_IMPORT_PATH}) if (NOT name) message(FATAL_ERROR "Must specify the NAME argument") endif() - if (${KIND} IN_LIST RUN_LABELS) + if (${KIND} IN_LIST labels) if (KIND STREQUAL "llvm") - if (import_path) - add_custom_command( - OUTPUT ${name}.o - COMMAND lpython -c -I ${CMAKE_CURRENT_SOURCE_DIR}/${import_path} ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.o - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py - VERBATIM) - else () - add_custom_command( - OUTPUT ${name}.o - COMMAND lpython -c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.o - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py - VERBATIM) - endif() - add_executable(${name} ${name}.o ${RUN_EXTRAFILES}) + add_custom_command( + OUTPUT ${name}.o + COMMAND ${LPYTHON} -c ${extra_args} ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}.o + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py + VERBATIM) + add_executable(${name} ${name}.o ${extra_files}) set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) target_link_libraries(${name} lpython_rtlib) add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) - if (RUN_LABELS) - set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") endif() - if (${RUN_FAIL}) + if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() - elseif(KIND STREQUAL "c") - if (import_path) - add_custom_command( - OUTPUT ${name}.c - COMMAND lpython -I ${CMAKE_CURRENT_SOURCE_DIR}/${import_path} --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py > ${name}.c - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py - VERBATIM) - else () - add_custom_command( - OUTPUT ${name}.c - COMMAND lpython --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py > ${name}.c - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py - VERBATIM) + elseif (KIND STREQUAL "llvm_jit") + add_test( + NAME ${name} + COMMAND ${LPYTHON} --jit ${extra_args} ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") endif() - - add_executable(${name} ${name}.c ${RUN_EXTRAFILES}) + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + elseif (KIND STREQUAL "llvm_py") + add_custom_command( + OUTPUT ${name}.o + COMMAND ${LPYTHON} -c ${extra_args} ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}.o + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py + VERBATIM) + add_executable(${name} ${name}.o ${extra_files}) + target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR} ${NUMPY_INCLUDE_DIR}) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + target_link_libraries(${name} lpython_rtlib Python::Python) + add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + elseif(KIND STREQUAL "llvm_sym") + add_custom_command( + OUTPUT ${name}.o + COMMAND ${LPYTHON} -c ${extra_args} ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}.o + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py + VERBATIM) + add_executable(${name} ${name}.o ${extra_files}) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + if (APPLE) + set(SYMENGINE_LIB "${Python_LIBRARY_DIRS}/libsymengine.dylib") + else() + set(SYMENGINE_LIB "${Python_LIBRARY_DIRS}/libsymengine.so") + endif() + target_link_libraries(${name} lpython_rtlib ${SYMENGINE_LIB}) + add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + elseif(KIND STREQUAL "c") + add_custom_command( + OUTPUT ${name}.c + COMMAND ${LPYTHON} ${extra_args} --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py > ${name}.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py + VERBATIM) + add_executable(${name} ${name}.c ${extra_files}) + target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR}) set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) target_link_libraries(${name} lpython_rtlib) add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) - if (RUN_LABELS) - set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") endif() - if (${RUN_FAIL}) + if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() - elseif(KIND STREQUAL "cpython") + elseif(KIND STREQUAL "c_py") + add_custom_command( + OUTPUT ${name}.c + COMMAND ${LPYTHON} ${extra_args} --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py > ${name}.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py + VERBATIM) + add_executable(${name} ${name}.c ${extra_files}) + target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR} ${NUMPY_INCLUDE_DIR}) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + target_link_libraries(${name} lpython_rtlib Python::Python) + add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + elseif(KIND STREQUAL "c_sym") + add_custom_command( + OUTPUT ${name}.c + COMMAND ${LPYTHON} ${extra_args} --show-c + ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py > ${name}.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py + VERBATIM) + add_executable(${name} ${name}.c ${extra_files}) + target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR} + "${Python_INCLUDE_DIRS}/..") + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + if (APPLE) + set(SYMENGINE_LIB "${Python_LIBRARY_DIRS}/libsymengine.dylib") + else() + set(SYMENGINE_LIB "${Python_LIBRARY_DIRS}/libsymengine.so") + endif() + target_link_libraries(${name} lpython_rtlib ${SYMENGINE_LIB}) + add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + elseif((KIND STREQUAL "cpython") OR (KIND STREQUAL "cpython_sym")) # CPython test - if (RUN_EXTRAFILES) + if (extra_files) set(PY_MOD "${name}_mod") - add_library(${PY_MOD} SHARED ${RUN_EXTRAFILES}) + add_library(${PY_MOD} SHARED ${extra_files}) set_target_properties(${PY_MOD} PROPERTIES LINKER_LANGUAGE C) else() set(PY_MOD "") endif() - add_test(${name} python ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py) - set_tests_properties(${name} PROPERTIES - ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/ltypes:${CMAKE_SOURCE_DIR}/..;LPYTHON_PY_MOD_NAME=${PY_MOD};LPYTHON_PY_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}") - if (RUN_LABELS) - set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + add_test(${name} python ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py) + if (no_mod) + set_tests_properties(${name} PROPERTIES + ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/lpython:${CMAKE_SOURCE_DIR}/..") + else() + set_tests_properties(${name} PROPERTIES + ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/lpython:${CMAKE_SOURCE_DIR}/..;LPYTHON_PY_MOD_NAME=${PY_MOD};LPYTHON_PY_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}") endif() - if (${RUN_FAIL}) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() elseif(KIND STREQUAL "x86") # x86 test add_custom_command( OUTPUT ${name}.x86 - COMMAND lpython --backend x86 ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.x86 - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + COMMAND ${LPYTHON} ${extra_args} --backend x86 ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}.x86 + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py VERBATIM ) add_custom_target(${name} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}.x86) add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.x86) - if (RUN_LABELS) - set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") endif() - if (${RUN_FAIL}) + if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() elseif(KIND STREQUAL "wasm_x86") # wasm_to_x86 test add_custom_command( OUTPUT ${name}.x86 - COMMAND lpython --backend wasm_x86 ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.x86 - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + COMMAND ${LPYTHON} ${extra_args} --backend wasm_x86 ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}.x86 + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py VERBATIM ) add_custom_target(${name} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}.x86) add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.x86) - if (RUN_LABELS) - set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") endif() - if (${RUN_FAIL}) + if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() elseif(KIND STREQUAL "wasm_x64") # wasm_to_x64 test add_custom_command( OUTPUT ${name}.x64 - COMMAND lpython --backend wasm_x64 ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.x64 - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + COMMAND ${LPYTHON} ${extra_args} --backend wasm_x64 ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}.x64 + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py VERBATIM ) add_custom_target(${name} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}.x64) add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.x64) - if (RUN_LABELS) - set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") endif() - if (${RUN_FAIL}) + if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() elseif(KIND STREQUAL "wasm") # wasm test - execute_process(COMMAND lpython --backend wasm ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}) + execute_process(COMMAND ${LPYTHON} ${extra_args} --backend wasm ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py -o ${name}) find_program(WASM_EXEC_RUNTIME node) execute_process(COMMAND "${WASM_EXEC_RUNTIME}" --version OUTPUT_VARIABLE WASM_EXEC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) - string(COMPARE GREATER_EQUAL "${WASM_EXEC_VERSION}" - "v16.0.0" IS_NODE_ABOVE_16) - if (NOT IS_NODE_ABOVE_16) + string(REGEX REPLACE "v([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" NODE_MAJOR_VERSION "${WASM_EXEC_VERSION}") + + if (NODE_MAJOR_VERSION LESS 16) message(STATUS "${WASM_EXEC_RUNTIME} version: ${WASM_EXEC_VERSION}") set(WASM_EXEC_FLAGS "--experimental-wasm-bigint") endif() set(WASM_EXEC_FLAGS ${WASM_EXEC_FLAGS} "--experimental-wasi-unstable-preview1") add_test(${name} ${WASM_EXEC_RUNTIME} ${WASM_EXEC_FLAGS} ${CMAKE_CURRENT_BINARY_DIR}/${name}.js) + if (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + endif() + + if (copy_to_bin) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/${copy_to_bin} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + endif() + + endif() +endmacro(RUN_UTIL) + +macro(RUN) + set(options FAIL NOFAST NOMOD) + set(oneValueArgs NAME IMPORT_PATH COPY_TO_BIN REQ_PY_VER) + set(multiValueArgs LABELS EXTRAFILES EXTRA_ARGS) + cmake_parse_arguments(RUN "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + set(RUN_FILE_NAME ${RUN_NAME}) + + if (RUN_IMPORT_PATH) + # Only one import path supported for now + # Later add support for multiple import paths by looping over and appending to extra args + set(RUN_EXTRA_ARGS ${RUN_EXTRA_ARGS} -I${CMAKE_CURRENT_SOURCE_DIR}/${RUN_IMPORT_PATH}) + endif() + + if (RUN_REQ_PY_VER) + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" PY_MAJOR_VERSION "${Python_VERSION}") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" PY_MINOR_VERSION "${Python_VERSION}") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1" REQ_PY_MAJOR_VERSION "${RUN_REQ_PY_VER}") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\2" REQ_PY_MINOR_VERSION "${RUN_REQ_PY_VER}") + + if (PY_MINOR_VERSION LESS REQ_PY_MINOR_VERSION) + # remove backends from the test that depend on CPython + list(REMOVE_ITEM RUN_LABELS cpython cpython_sym c_py c_sym llvm_sym llvm_py) + endif() + endif() + + if (NOT FAST) + RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_NOMOD RUN_EXTRA_ARGS RUN_COPY_TO_BIN) + endif() + + if ((FAST) AND (NOT RUN_NOFAST)) + set(RUN_EXTRA_ARGS ${RUN_EXTRA_ARGS} --fast) + set(RUN_NAME "${RUN_NAME}_FAST") + list(REMOVE_ITEM RUN_LABELS cpython cpython_sym) # remove cpython, cpython_sym, from --fast test + RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_NOMOD RUN_EXTRA_ARGS RUN_COPY_TO_BIN) + endif() +endmacro(RUN) + +# only compiles till object file +# to make sure that the generated code is syntactically correct +# but we cannot generate an executable due to --disable-main option enabled. +macro(COMPILE) + set(options FAIL) + set(oneValueArgs NAME IMPORT_PATH) + set(multiValueArgs LABELS EXTRAFILES) + cmake_parse_arguments(COMPILE "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + set(name ${COMPILE_NAME}) + if (NOT name) + message(FATAL_ERROR "Must specify the NAME argument") + endif() + + set(extra_args "") + if (COMPILE_IMPORT_PATH) + # Only one import path supported for now + # Later add support for multiple import paths by looping over and appending to extra args + set(extra_args ${extra_args} -I${CMAKE_CURRENT_SOURCE_DIR}/${COMPILE_IMPORT_PATH}) + endif() + + if (${KIND} IN_LIST COMPILE_LABELS) + if (KIND STREQUAL "llvm") + add_custom_command( + OUTPUT ${name}.o + COMMAND ${LPYTHON} ${extra_args} --disable-main -c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.o + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + VERBATIM) + add_library(${name} OBJECT ${name}.o) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + elseif(KIND STREQUAL "c") + add_custom_command( + OUTPUT ${name}.c + COMMAND ${LPYTHON} ${extra_args} --disable-main --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py > ${name}.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + VERBATIM) + add_library(${name} OBJECT ${name}.c) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + target_link_libraries(${name} lpython_rtlib) + elseif(KIND STREQUAL "cpython") + # CPython test + set(PY_MOD "") + + add_test(${name} python ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py) + set_tests_properties(${name} PROPERTIES + ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/lpython:${CMAKE_SOURCE_DIR}/..;LPYTHON_PY_MOD_NAME=${PY_MOD};LPYTHON_PY_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}") if (RUN_LABELS) set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") endif() @@ -201,228 +413,454 @@ macro(RUN) endif() endif() endif() -endmacro(RUN) +endmacro(COMPILE) # Test zero and non-zero exit code and assert statements -RUN(NAME array_01_decl LABELS cpython llvm c) -RUN(NAME array_02_decl LABELS cpython llvm c) -RUN(NAME array_03_decl LABELS cpython llvm c) -RUN(NAME variable_decl_01 LABELS cpython llvm c) -RUN(NAME variable_decl_02 LABELS cpython llvm c) -RUN(NAME array_expr_01 LABELS cpython llvm) -RUN(NAME array_expr_02 LABELS cpython llvm) -RUN(NAME array_01 LABELS cpython llvm wasm) -RUN(NAME array_02 LABELS cpython wasm) -RUN(NAME bindc_01 LABELS cpython llvm c) -RUN(NAME bindc_02 LABELS cpython llvm c) -RUN(NAME bindc_04 LABELS llvm c) -RUN(NAME bindc_07 LABELS cpython llvm c) -RUN(NAME exit_01 LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME exit_02 FAIL LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME exit_01b LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME exit_02b FAIL LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME exit_02c FAIL LABELS cpython llvm c) +RUN(NAME array_01_decl LABELS cpython llvm llvm_jit c) +RUN(NAME array_02_decl LABELS cpython llvm llvm_jit c) +RUN(NAME array_03_decl LABELS cpython llvm llvm_jit) # renable c +RUN(NAME variable_decl_01 LABELS cpython llvm llvm_jit c) +RUN(NAME variable_decl_02 LABELS cpython llvm llvm_jit c) +RUN(NAME variable_decl_03 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_01 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_02 LABELS cpython llvm llvm_jit c NOFAST) # post sync +RUN(NAME array_expr_03 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_04 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_05 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_06 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_07 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_08 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_09 LABELS cpython llvm llvm_jit c) +RUN(NAME array_expr_10 LABELS cpython llvm llvm_jit c) # post sync +RUN(NAME array_size_01 LABELS cpython llvm llvm_jit c) +RUN(NAME array_size_02 LABELS cpython llvm llvm_jit c) +RUN(NAME array_01 LABELS cpython llvm llvm_jit wasm c) +RUN(NAME array_02 LABELS cpython wasm c) +RUN(NAME array_03 LABELS cpython llvm llvm_jit c) +RUN(NAME array_04 LABELS cpython llvm llvm_jit c) +RUN(NAME array_05 LABELS cpython llvm llvm_jit c) +RUN(NAME array_06 LABELS cpython llvm llvm_jit) +# RUN(NAME bindc_01 LABELS cpython llvm llvm_jit c) +# RUN(NAME bindc_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME bindc_04 LABELS llvm llvm_jit c NOFAST) +# RUN(NAME bindc_07 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME bindc_08 LABELS cpython llvm llvm_jit c) +# RUN(NAME bindc_09 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME bindc_09b LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME bindc_10 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME bindc_11 LABELS cpython) # This is CPython test only +RUN(NAME exit_01 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME exit_02 FAIL LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME exit_03 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME exit_04 FAIL LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME exit_01b LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME exit_02b FAIL LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME exit_02c FAIL LABELS cpython llvm llvm_jit c) # Test all four backends -RUN(NAME print_01 LABELS cpython llvm c wasm) # wasm not yet supports sep and end keywords +RUN(NAME print_01 LABELS cpython llvm llvm_jit) # renable c, wasm not yet supports sep and end keywords, wasm does not handle DescriptorString RUN(NAME print_03 LABELS x86 c wasm wasm_x86 wasm_x64) # simple test case specifically for x86, wasm_x86 and wasm_x64 -RUN(NAME print_04 LABELS cpython llvm c) -RUN(NAME print_05 LABELS cpython llvm wasm wasm_x64) -RUN(NAME print_float LABELS cpython llvm wasm wasm_x64) -RUN(NAME print_list_tuple LABELS cpython c) # TODO: llvm doesn't completely support printing list +RUN(NAME print_04 LABELS cpython llvm llvm_jit c) +RUN(NAME print_06 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME print_05 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME print_float LABELS cpython llvm llvm_jit c wasm wasm_x64) +# RUN(NAME print_list_tuple_01 LABELS cpython llvm llvm_jit NOFAST) # renable c # post sync +# RUN(NAME print_list_tuple_02 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME print_list_tuple_03 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_list_item_mixed_print LABELS cpython llvm llvm_jit NOFAST) # renable c # post sync +# RUN(NAME test_intrinsic_function_mixed_print LABELS cpython llvm llvm_jit NOFAST) # post sync # CPython and LLVM -RUN(NAME const_01 LABELS cpython llvm c) -RUN(NAME const_02 LABELS cpython llvm c) +RUN(NAME const_01 LABELS cpython llvm llvm_jit c wasm) +RUN(NAME const_02 LABELS cpython llvm llvm_jit c wasm) RUN(NAME const_03 LABELS cpython llvm c EXTRAFILES const_03b.c) -RUN(NAME const_04 LABELS cpython llvm c) -RUN(NAME expr_01 LABELS cpython llvm c wasm wasm_x64) -RUN(NAME expr_02 LABELS cpython llvm c wasm wasm_x64) -RUN(NAME expr_03 LABELS cpython llvm c wasm wasm_x64) -RUN(NAME expr_04 LABELS cpython llvm c wasm) -RUN(NAME expr_05 LABELS cpython llvm c) -RUN(NAME expr_06 LABELS cpython llvm c) -RUN(NAME expr_07 LABELS cpython llvm c) -RUN(NAME expr_08 LABELS llvm c) -RUN(NAME expr_09 LABELS cpython llvm c) -RUN(NAME expr_10 LABELS cpython llvm c) -RUN(NAME expr_11 LABELS cpython llvm c wasm) -RUN(NAME expr_12 LABELS llvm c) -RUN(NAME expr_13 LABELS llvm c - EXTRAFILES expr_13b.c) -RUN(NAME expr_14 LABELS cpython llvm c) -RUN(NAME loop_01 LABELS cpython llvm c) -RUN(NAME loop_02 LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME loop_03 LABELS cpython llvm c wasm wasm_x64) -RUN(NAME loop_04 LABELS cpython llvm) -RUN(NAME if_01 LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME if_02 LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME print_02 LABELS cpython llvm c) -RUN(NAME test_types_01 LABELS cpython llvm c) -RUN(NAME test_str_01 LABELS cpython llvm c) -RUN(NAME test_str_02 LABELS cpython llvm c) -RUN(NAME test_str_03 LABELS cpython llvm c) -RUN(NAME test_list_01 LABELS cpython llvm c) -RUN(NAME test_list_02 LABELS cpython llvm c) -RUN(NAME test_list_03 LABELS cpython llvm c) -RUN(NAME test_list_04 LABELS cpython llvm c) -RUN(NAME test_list_05 LABELS cpython llvm c) -RUN(NAME test_list_06 LABELS cpython llvm c) -RUN(NAME test_list_07 LABELS cpython llvm c) -RUN(NAME test_list_08 LABELS cpython llvm c) -RUN(NAME test_list_09 LABELS cpython llvm c) -RUN(NAME test_list_10 LABELS cpython llvm c) -RUN(NAME test_list_section LABELS cpython llvm c) -RUN(NAME test_tuple_01 LABELS cpython llvm c) -RUN(NAME test_tuple_02 LABELS cpython llvm c) -RUN(NAME test_dict_01 LABELS cpython llvm) -RUN(NAME test_dict_02 LABELS cpython llvm) -RUN(NAME test_dict_03 LABELS cpython llvm) -RUN(NAME test_dict_04 LABELS cpython llvm) -RUN(NAME test_dict_05 LABELS cpython llvm) -RUN(NAME test_for_loop LABELS cpython llvm c) -RUN(NAME modules_01 LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME modules_02 LABELS cpython llvm c wasm wasm_x86 wasm_x64) -RUN(NAME test_import_01 LABELS cpython llvm c) -RUN(NAME test_import_02 LABELS cpython llvm c) -RUN(NAME test_import_03 LABELS cpython llvm c) -RUN(NAME test_import_04 IMPORT_PATH .. - LABELS cpython llvm c) -RUN(NAME test_math LABELS cpython llvm) -RUN(NAME test_numpy_01 LABELS cpython llvm c) -RUN(NAME test_numpy_02 LABELS cpython llvm c) -RUN(NAME test_numpy_03 LABELS cpython llvm c) -RUN(NAME test_numpy_04 LABELS cpython llvm c) -RUN(NAME elemental_01 LABELS cpython llvm) -RUN(NAME elemental_02 LABELS cpython llvm) -RUN(NAME elemental_03 LABELS cpython llvm) -RUN(NAME elemental_04 LABELS cpython llvm) -RUN(NAME elemental_05 LABELS cpython llvm) -RUN(NAME elemental_06 LABELS cpython llvm) -RUN(NAME elemental_07 LABELS cpython llvm) -RUN(NAME elemental_08 LABELS cpython llvm) -RUN(NAME elemental_09 LABELS cpython llvm) -RUN(NAME elemental_10 LABELS cpython llvm) -RUN(NAME elemental_11 LABELS cpython llvm) -RUN(NAME elemental_12 LABELS cpython llvm c) -RUN(NAME test_random LABELS cpython llvm) -RUN(NAME test_os LABELS cpython llvm c) -RUN(NAME test_builtin LABELS cpython llvm c) -RUN(NAME test_builtin_abs LABELS cpython llvm c) -RUN(NAME test_builtin_bool LABELS cpython llvm c) -RUN(NAME test_builtin_pow LABELS cpython llvm c) -RUN(NAME test_builtin_int LABELS cpython llvm c) -RUN(NAME test_builtin_len LABELS cpython llvm c) -RUN(NAME test_builtin_str LABELS cpython llvm c) -RUN(NAME test_builtin_oct LABELS cpython llvm c) -RUN(NAME test_builtin_hex LABELS cpython llvm c) -RUN(NAME test_builtin_bin LABELS cpython llvm c) -RUN(NAME test_builtin_float LABELS cpython llvm c) -RUN(NAME test_builtin_str_02 LABELS cpython llvm c) -RUN(NAME test_builtin_round LABELS cpython llvm c) -RUN(NAME test_builtin_divmod LABELS cpython llvm c) -RUN(NAME test_math1 LABELS cpython llvm c) -RUN(NAME test_math_02 LABELS cpython llvm) -RUN(NAME test_pass_compare LABELS cpython llvm c) -RUN(NAME test_c_interop_01 LABELS cpython llvm c) -RUN(NAME test_c_interop_02 LABELS cpython llvm c - EXTRAFILES test_c_interop_02b.c) -RUN(NAME test_c_interop_03 LABELS cpython llvm c - EXTRAFILES test_c_interop_03b.c) -RUN(NAME test_c_interop_04 LABELS cpython llvm c - EXTRAFILES test_c_interop_04b.c) -RUN(NAME test_c_interop_05 LABELS llvm c - EXTRAFILES test_c_interop_05b.c) -RUN(NAME bindc_03 LABELS llvm c - EXTRAFILES bindc_03b.c) -RUN(NAME bindc_05 LABELS llvm c - EXTRAFILES bindc_05b.c) -RUN(NAME bindc_06 LABELS llvm c - EXTRAFILES bindc_06b.c) -RUN(NAME test_generics_01 LABELS cpython llvm c) -RUN(NAME test_cmath LABELS cpython llvm c) -RUN(NAME test_complex LABELS cpython llvm c) -RUN(NAME test_max_min LABELS cpython llvm c) -RUN(NAME test_global LABELS cpython llvm c) -RUN(NAME test_global_decl LABELS cpython llvm c) -RUN(NAME test_integer_bitnot LABELS cpython llvm c wasm) -RUN(NAME test_ifexp LABELS cpython llvm c) -RUN(NAME test_unary_minus LABELS cpython llvm c) -RUN(NAME test_unary_plus LABELS cpython llvm c) -RUN(NAME test_bool_binop LABELS cpython llvm c) -RUN(NAME test_issue_518 LABELS cpython llvm c) -RUN(NAME structs_01 LABELS cpython llvm c) -RUN(NAME structs_02 LABELS cpython llvm c) -RUN(NAME structs_03 LABELS llvm c) -RUN(NAME structs_04 LABELS cpython llvm c) -RUN(NAME structs_05 LABELS llvm c) -RUN(NAME structs_06 LABELS cpython llvm c) -RUN(NAME structs_07 LABELS llvm c - EXTRAFILES structs_07b.c) -RUN(NAME structs_08 LABELS cpython llvm c) -RUN(NAME structs_09 LABELS cpython llvm c) -RUN(NAME structs_10 LABELS cpython llvm c) -RUN(NAME structs_11 LABELS cpython llvm c) -RUN(NAME structs_12 LABELS cpython llvm c) -RUN(NAME structs_13 LABELS llvm c - EXTRAFILES structs_13b.c) -RUN(NAME structs_14 LABELS cpython llvm c) -RUN(NAME structs_15 LABELS cpython llvm c) -RUN(NAME structs_16 LABELS cpython llvm c) -RUN(NAME structs_17 LABELS cpython llvm c) -RUN(NAME structs_18 LABELS cpython llvm c - EXTRAFILES structs_18b.c) -RUN(NAME structs_19 LABELS cpython llvm c - EXTRAFILES structs_19b.c) -RUN(NAME structs_20 LABELS cpython llvm c - EXTRAFILES structs_20b.c) -RUN(NAME structs_21 LABELS cpython llvm c) -RUN(NAME sizeof_01 LABELS llvm c - EXTRAFILES sizeof_01b.c) -RUN(NAME enum_01 LABELS cpython llvm c) -RUN(NAME enum_02 LABELS cpython llvm) -RUN(NAME enum_03 LABELS cpython llvm c) -RUN(NAME enum_04 LABELS cpython llvm c) -RUN(NAME enum_05 LABELS llvm c - EXTRAFILES enum_05b.c) -RUN(NAME enum_06 LABELS cpython llvm c) -RUN(NAME union_01 LABELS cpython llvm c) -RUN(NAME union_02 LABELS llvm c) -RUN(NAME union_03 LABELS cpython llvm c) -RUN(NAME test_str_to_int LABELS cpython llvm c) -RUN(NAME test_platform LABELS cpython llvm c) -RUN(NAME test_vars_01 LABELS cpython llvm) -RUN(NAME test_version LABELS cpython llvm) -RUN(NAME logical_binop1 LABELS cpython llvm) -RUN(NAME vec_01 LABELS cpython llvm c) -RUN(NAME test_str_comparison LABELS cpython llvm c) -RUN(NAME test_bit_length LABELS cpython llvm c) -RUN(NAME str_to_list_cast LABELS cpython llvm c) - -RUN(NAME generics_01 LABELS cpython llvm c) -RUN(NAME generics_02 LABELS cpython llvm c) -RUN(NAME generics_array_01 LABELS cpython llvm) -RUN(NAME generics_array_02 LABELS cpython llvm) -RUN(NAME generics_array_03 LABELS cpython llvm) -RUN(NAME generics_list_01 LABELS cpython llvm) -RUN(NAME test_statistics LABELS cpython llvm) -RUN(NAME test_str_attributes LABELS cpython llvm c) -RUN(NAME kwargs_01 LABELS cpython llvm c) -RUN(NAME test_01_goto LABELS cpython llvm c) - -RUN(NAME func_inline_01 LABELS llvm c wasm) -RUN(NAME func_inline_02 LABELS cpython llvm c) -RUN(NAME func_static_01 LABELS cpython llvm c wasm) -RUN(NAME func_static_02 LABELS cpython llvm c wasm) -RUN(NAME func_dep_03 LABELS cpython llvm c) -RUN(NAME func_dep_04 LABELS cpython llvm c) - -RUN(NAME float_01 LABELS cpython llvm wasm wasm_x64) -RUN(NAME recursive_01 LABELS cpython llvm wasm wasm_x64 wasm_x86) -RUN(NAME comp_01 LABELS cpython llvm wasm wasm_x64) -RUN(NAME bit_operations_i32 LABELS cpython llvm wasm wasm_x64) -RUN(NAME bit_operations_i64 LABELS cpython llvm wasm) - -RUN(NAME test_argv_01 LABELS llvm) # TODO: Test using CPython +# RUN(NAME const_04 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_01 LABELS cpython llvm llvm_jit c wasm) # renable wasm_x64 +RUN(NAME expr_02 LABELS cpython llvm llvm_jit c wasm) # renable wasm_x64 +RUN(NAME expr_03 LABELS cpython llvm llvm_jit c wasm) # renable wasm_x64 +RUN(NAME expr_04 LABELS cpython llvm llvm_jit c wasm NOFAST) +RUN(NAME expr_05 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME expr_06 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME expr_07 LABELS cpython llvm llvm_jit c) # string refactor +# RUN(NAME expr_08 LABELS llvm llvm_jit c NOFAST) +RUN(NAME expr_09 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_10 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_11 LABELS cpython llvm llvm_jit c wasm) +# RUN(NAME expr_12 LABELS llvm llvm_jit c) +# RUN(NAME expr_13 LABELS llvm c +# EXTRAFILES expr_13b.c NOFAST) +RUN(NAME expr_14 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_15 LABELS cpython llvm llvm_jit c) +# RUN(NAME expr_16 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_17 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_18 FAIL LABELS cpython llvm llvm_jit c) +RUN(NAME expr_19 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_20 LABELS cpython llvm llvm_jit c) +# RUN(NAME expr_21 LABELS cpython llvm llvm_jit c) # post sync +RUN(NAME expr_22 LABELS cpython llvm llvm_jit c) +RUN(NAME expr_23 LABELS cpython llvm llvm_jit c) +# RUN(NAME expr_24 LABELS cpython wasm) # mandelbrot + +RUN(NAME expr_01u LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME expr_02u LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME expr_03u LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME expr_04u LABELS cpython llvm llvm_jit c) + +RUN(NAME list_01 LABELS cpython llvm llvm_jit) + +RUN(NAME loop_01 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME loop_02 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME loop_03 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME loop_04 LABELS cpython llvm llvm_jit c) +RUN(NAME loop_05 LABELS cpython llvm llvm_jit c) +RUN(NAME loop_06 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME loop_07 LABELS cpython llvm llvm_jit c) +RUN(NAME loop_08 LABELS cpython llvm llvm_jit c) +RUN(NAME loop_09 LABELS cpython llvm llvm_jit) +RUN(NAME loop_10 LABELS cpython llvm llvm_jit) +# RUN(NAME loop_11 LABELS cpython llvm llvm_jit) +RUN(NAME if_01 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME if_02 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME if_03 FAIL LABELS cpython llvm llvm_jit NOFAST) # renable c +# RUN(NAME print_02 LABELS cpython llvm llvm_jit) # renable c # post sync +RUN(NAME test_types_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_types_02 LABELS cpython llvm llvm_jit c wasm) +# RUN(NAME test_str_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_str_02 LABELS cpython llvm llvm_jit) # renable c +# RUN(NAME test_str_03 LABELS cpython llvm llvm_jit) # renable c # str negative indexing +RUN(NAME test_str_04 LABELS cpython llvm llvm_jit) # renable c, wasm +RUN(NAME test_str_05 LABELS cpython llvm llvm_jit) # renable c +# RUN(NAME test_str_06 LABELS cpython llvm llvm_jit c) +RUN(NAME test_string_01 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_list_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_list_02 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_list_03 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME test_list_04 LABELS cpython llvm llvm_jit NOFAST) # renable c +# RUN(NAME test_list_05 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_list_06 LABELS cpython llvm llvm_jit c) +RUN(NAME test_list_07 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_list_08 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_list_09 LABELS cpython llvm llvm_jit NOFAST) # renable c +# RUN(NAME test_list_10 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_list_11 LABELS cpython llvm llvm_jit c) +# RUN(NAME test_list_section LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_list_section2 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_list_count LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_list_index LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_list_index2 LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_list_repeat LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_list_repeat2 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_list_reverse LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_list_pop LABELS cpython llvm llvm_jit NOFAST) # TODO: Remove NOFAST from here. +RUN(NAME test_list_pop2 LABELS cpython llvm llvm_jit NOFAST) # TODO: Remove NOFAST from here. +RUN(NAME test_list_pop3 LABELS cpython llvm llvm_jit) +# RUN(NAME test_list_compare LABELS cpython llvm llvm_jit) # post sync +RUN(NAME test_list_compare2 LABELS cpython llvm llvm_jit) +RUN(NAME test_list_concat LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_list_reserve LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_const_list LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_const_access LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_tuple_01 LABELS cpython llvm llvm_jit) # renable c # post sync +# RUN(NAME test_tuple_02 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_tuple_03 LABELS cpython llvm llvm_jit) # renable c # post sync +# RUN(NAME test_tuple_04 LABELS cpython llvm llvm_jit) # renable c # post sync +# RUN(NAME test_tuple_concat LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_tuple_nested LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_const_dict LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_params LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_dict_01 LABELS cpython llvm llvm_jit c) # post sync +RUN(NAME test_dict_02 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_dict_03 LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_dict_04 LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_dict_05 LABELS cpython llvm llvm_jit c) +RUN(NAME test_dict_06 LABELS cpython llvm llvm_jit c) +# RUN(NAME test_dict_07 LABELS cpython llvm llvm_jit c) +RUN(NAME test_dict_08 LABELS cpython llvm llvm_jit c) +RUN(NAME test_dict_09 LABELS cpython llvm llvm_jit c) +# RUN(NAME test_dict_10 LABELS cpython llvm llvm_jit) # renable c # post sync +# RUN(NAME test_dict_11 LABELS cpython llvm llvm_jit c) # post sync +RUN(NAME test_dict_12 LABELS cpython llvm) # renable c, jit +RUN(NAME test_dict_13 LABELS cpython llvm) # renable c, jit +# RUN(NAME test_dict_bool LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_dict_increment LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_dict_keys_values LABELS cpython llvm llvm_jit) +# RUN(NAME test_dict_nested1 LABELS cpython llvm llvm_jit) +# RUN(NAME test_dict_clear LABELS cpython llvm) +# RUN(NAME test_set_len LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_set_add LABELS cpython llvm llvm_jit) # post sync +# RUN(NAME test_set_remove LABELS cpython llvm llvm_jit) +# RUN(NAME test_set_discard LABELS cpython llvm llvm_jit) +# RUN(NAME test_set_from_list LABELS cpython llvm llvm_jit) +# RUN(NAME test_set_clear LABELS cpython llvm) +# RUN(NAME test_set_pop LABELS cpython llvm) +# RUN(NAME test_global_set LABELS cpython llvm llvm_jit) # post sync +RUN(NAME test_for_loop LABELS cpython llvm llvm_jit c) +RUN(NAME modules_01 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME modules_02 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME test_import_01 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_import_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_import_03 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_import_04 LABELS cpython llvm llvm_jit c) +RUN(NAME test_import_05 LABELS cpython llvm llvm_jit c wasm wasm_x86 wasm_x64) +RUN(NAME test_import_06 LABELS cpython llvm llvm_jit) +RUN(NAME test_import_07 LABELS cpython llvm llvm_jit c) +RUN(NAME test_import_08 LABELS cpython llvm) +RUN(NAME test_math LABELS cpython llvm llvm_jit NOFAST) +# RUN(NAME test_membership_01 LABELS cpython llvm) +RUN(NAME test_numpy_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_numpy_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_numpy_03 LABELS cpython llvm llvm_jit c) +RUN(NAME test_numpy_04 LABELS cpython llvm llvm_jit c) +RUN(NAME elemental_01 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_02 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_03 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_04 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_05 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_06 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_07 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_08 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_09 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_10 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_11 LABELS cpython llvm llvm_jit NOFAST) # renable c +RUN(NAME elemental_12 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_13 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_random LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_random_02 LABELS cpython llvm llvm_jit NOFAST) +# RUN(NAME test_os LABELS cpython llvm llvm_jit NOFAST) # renable c # post sync +# RUN(NAME test_builtin LABELS cpython llvm llvm_jit) # renable c # post sync +RUN(NAME test_builtin_abs LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_bool LABELS cpython llvm llvm_jit c) +RUN(NAME test_builtin_pow LABELS cpython llvm llvm_jit c EXTRA_ARGS --no-warnings) +# RUN(NAME test_builtin_int LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_len LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_str LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_oct LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_hex LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_bin LABELS cpython llvm llvm_jit c) +RUN(NAME test_builtin_float LABELS cpython llvm llvm_jit c) +# RUN(NAME test_builtin_str_02 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_builtin_round LABELS cpython llvm llvm_jit c) +RUN(NAME test_builtin_divmod LABELS cpython llvm llvm_jit c) +RUN(NAME test_builtin_sum LABELS cpython llvm llvm_jit c) +RUN(NAME test_math1 LABELS cpython llvm llvm_jit c) +RUN(NAME test_math_02 LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_math_03 LABELS llvm llvm_jit) #1595: TODO: Test using CPython (3.11 recommended) +# RUN(NAME test_pass_compare LABELS cpython llvm llvm_jit) # renable c # post sync +RUN(NAME test_c_interop_01 LABELS cpython llvm llvm_jit c) +# RUN(NAME test_c_interop_02 LABELS cpython llvm c +# EXTRAFILES test_c_interop_02b.c) +# RUN(NAME test_c_interop_03 LABELS cpython llvm c + # EXTRAFILES test_c_interop_03b.c) +# RUN(NAME test_c_interop_04 LABELS cpython llvm llvm_jit c +# EXTRAFILES test_c_interop_04b.c) +# RUN(NAME test_c_interop_05 LABELS llvm c +# EXTRAFILES test_c_interop_05b.c) +# RUN(NAME bindc_03 LABELS llvm c +# EXTRAFILES bindc_03b.c) +# RUN(NAME bindc_05 LABELS llvm c +# EXTRAFILES bindc_05b.c) +# RUN(NAME bindc_06 LABELS llvm +# EXTRAFILES bindc_06b.c) # renable c +# RUN(NAME bindpy_01 LABELS cpython llvm_py c_py EXTRA_ARGS --enable-cpython NOFAST COPY_TO_BIN bindpy_01_module.py) +# RUN(NAME bindpy_02 LABELS cpython c_py EXTRA_ARGS --link-numpy COPY_TO_BIN bindpy_02_module.py) +# RUN(NAME bindpy_03 LABELS cpython c_py EXTRA_ARGS --link-numpy NOFAST COPY_TO_BIN bindpy_03_module.py) +# RUN(NAME bindpy_04 LABELS cpython c_py EXTRA_ARGS --link-numpy NOFAST COPY_TO_BIN bindpy_04_module.py) +# RUN(NAME bindpy_05 LABELS llvm_py c_py EXTRA_ARGS --enable-cpython COPY_TO_BIN bindpy_05_module.py REQ_PY_VER 3.10) +# RUN(NAME bindpy_06 LABELS cpython llvm_py EXTRA_ARGS --enable-cpython NOFAST COPY_TO_BIN bindpy_06_module.py REQ_PY_VER 3.10) +# RUN(NAME test_generics_01 LABELS cpython llvm llvm_jit NOFAST) # renable c # post sync +RUN(NAME test_cmath LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_complex_01 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME test_complex_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_ConstantEllipsis LABLES cpython llvm llvm_jit c) +RUN(NAME test_max_min LABELS cpython llvm llvm_jit c) +RUN(NAME test_global LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_global_decl LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_ifexp_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_ifexp_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_ifexp_03 LABELS cpython llvm llvm_jit c) +RUN(NAME test_unary_op_01 LABELS cpython llvm llvm_jit c) # unary minus +RUN(NAME test_unary_op_02 LABELS cpython llvm llvm_jit c) # unary plus +RUN(NAME test_unary_op_03 LABELS cpython llvm llvm_jit c wasm) # unary bitinvert +RUN(NAME test_unary_op_04 LABELS cpython llvm llvm_jit c) # unary bitinvert +RUN(NAME test_unary_op_05 LABELS cpython llvm llvm_jit c) # unsigned unary minus, plus +RUN(NAME test_unary_op_06 LABELS cpython llvm llvm_jit c) # unsigned unary bitnot +RUN(NAME test_unsigned_01 LABELS cpython llvm llvm_jit c) # unsigned bitshift left, right +RUN(NAME test_unsigned_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_unsigned_03 LABELS cpython llvm llvm_jit c) +RUN(NAME test_bool_binop LABELS cpython llvm llvm_jit c) +RUN(NAME test_issue_518 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME structs_01 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_02b LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME structs_03 LABELS llvm llvm_jit c) +# RUN(NAME structs_04 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_05 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_06 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_07 LABELS llvm c +# EXTRAFILES structs_07b.c) +# RUN(NAME structs_08 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_09 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_10 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME structs_11 LABELS cpython llvm llvm_jit c) +RUN(NAME structs_12 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_13 LABELS llvm c +# EXTRAFILES structs_13b.c) +RUN(NAME structs_14 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_15 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_16 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_17 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_18 LABELS cpython llvm c +# EXTRAFILES structs_18b.c) +# RUN(NAME structs_19 LABELS cpython llvm c +# EXTRAFILES structs_19b.c) +# RUN(NAME structs_20 LABELS cpython llvm c +# EXTRAFILES structs_20b.c) +# RUN(NAME structs_21 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_22 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME structs_23 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME structs_24 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_25 LABELS cpython llvm llvm_jit c) # post sync +RUN(NAME structs_26 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME structs_27 LABELS cpython llvm llvm_jit) # renable c +RUN(NAME structs_28 LABELS cpython llvm llvm_jit) # renable c +# RUN(NAME structs_29 LABELS cpython llvm llvm_jit) +RUN(NAME structs_30 LABELS cpython llvm llvm_jit) # renable c +# RUN(NAME structs_31 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_32 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_33 LABELS cpython llvm llvm_jit c) +# RUN(NAME structs_34 LABELS cpython llvm llvm_jit c) +RUN(NAME structs_35 LABELS cpython llvm llvm_jit) + +# RUN(NAME symbolics_01 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_02 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_03 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_04 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_05 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_06 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_07 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_08 LABELS cpython_sym llvm_sym llvm_jit EXTRA_ARGS --enable-symengine) # renable c_sym +# RUN(NAME symbolics_09 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_10 LABELS cpython_sym c_sym llvm_sym NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_11 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_12 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_13 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_14 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME test_gruntz LABELS cpython_sym c_sym llvm_sym NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_15 LABELS c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_16 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_17 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME symbolics_18 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) +# RUN(NAME gruntz_demo3 LABELS cpython_sym c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) + +# RUN(NAME sizeof_01 LABELS llvm c +# EXTRAFILES sizeof_01b.c) +# RUN(NAME sizeof_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME enum_01 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME enum_02 LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME enum_03 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME enum_04 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME enum_05 LABELS llvm c +# EXTRAFILES enum_05b.c NOFAST) +# RUN(NAME enum_06 LABELS cpython llvm llvm_jit c) +RUN(NAME enum_07 IMPORT_PATH .. + LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME union_01 LABELS cpython llvm llvm_jit c) +# RUN(NAME union_02 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME union_03 LABELS cpython llvm llvm_jit c) +RUN(NAME union_04 IMPORT_PATH .. + LABELS cpython llvm llvm_jit c) +# RUN(NAME test_str_to_int LABELS cpython llvm llvm_jit c) +# RUN(NAME test_platform LABELS cpython llvm llvm_jit) # renable c +RUN(NAME test_vars_01 LABELS cpython llvm llvm_jit) +# RUN(NAME test_version LABELS cpython llvm llvm_jit) # post sync +RUN(NAME logical_binop1 LABELS cpython llvm llvm_jit) +# RUN(NAME test_logical_compare LABELS cpython llvm llvm_jit) # TODO: Add C backend after fixing issue #2708 +# RUN(NAME test_logical_assignment LABELS cpython llvm llvm_jit) # TODO: Add C backend after fixing issue #2708 +RUN(NAME vec_01 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME test_str_comparison LABELS cpython llvm llvm_jit c wasm) +RUN(NAME test_bit_length LABELS cpython) # renable c, FIXME: This test fails on llvm & llvm_jit +# RUN(NAME str_to_list_cast LABELS cpython llvm llvm_jit c) +# RUN(NAME cast_01 LABELS cpython llvm llvm_jit c) +# RUN(NAME cast_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME test_sys_01 LABELS cpython llvm llvm_jit c NOFAST) +# RUN(NAME intent_01 LABELS cpython llvm llvm_jit) + + +# RUN(NAME test_package_01 LABELS cpython llvm llvm_jit NOFAST) +# RUN(NAME test_pkg_lpdraw LABELS cpython llvm llvm_jit wasm) +# RUN(NAME test_pkg_lnn_01 LABELS cpython llvm llvm_jit NOFAST) +# RUN(NAME test_pkg_lnn_02 LABELS cpython llvm llvm_jit NOFAST) +# RUN(NAME test_pkg_lpconvexhull LABELS cpython llvm llvm_jit c NOFAST) + +# RUN(NAME generics_01 LABELS cpython llvm llvm_jit) # renable c # post sync +# RUN(NAME generics_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME generics_array_01 LABELS cpython llvm llvm_jit c) +# RUN(NAME generics_array_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME generics_array_03 LABELS cpython llvm llvm_jit c) +# RUN(NAME generics_list_01 LABELS cpython llvm llvm_jit) # renable c # post sync +RUN(NAME test_statistics_01 LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_statistics_02 LABELS cpython llvm llvm_jit NOFAST REQ_PY_VER 3.10) +# RUN(NAME test_attributes LABELS cpython llvm llvm_jit) +# RUN(NAME test_str_attributes LABELS cpython llvm llvm_jit c) +RUN(NAME kwargs_01 LABELS cpython llvm llvm_jit NOFAST) # renable c # post sync +RUN(NAME def_func_01 LABELS cpython llvm llvm_jit) # renable c # post sync + +RUN(NAME func_inline_01 LABELS llvm llvm_jit c wasm) +RUN(NAME func_inline_02 LABELS cpython llvm llvm_jit c) +RUN(NAME func_static_01 LABELS cpython llvm llvm_jit c wasm) +RUN(NAME func_static_02 LABELS cpython llvm llvm_jit c wasm) +RUN(NAME func_dep_03 LABELS cpython llvm llvm_jit c) +RUN(NAME func_dep_04 LABELS cpython llvm llvm_jit c) +RUN(NAME func_internal_def_01 LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME func_01 LABELS cpython llvm llvm_jit) +RUN(NAME func_02 LABELS c_sym llvm_sym llvm_jit NOFAST EXTRA_ARGS --enable-symengine) + +RUN(NAME float_01 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME recursive_01 LABELS cpython llvm llvm_jit c wasm wasm_x64 wasm_x86) +RUN(NAME comp_01 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME bit_operations_i32 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME bit_operations_i64 LABELS cpython llvm llvm_jit c wasm) + +# RUN(NAME test_argv_01 LABELS cpython llvm NOFAST) +RUN(NAME global_syms_01 LABELS cpython llvm llvm_jit c) +RUN(NAME global_syms_02 LABELS cpython llvm llvm_jit c) +# RUN(NAME global_syms_03_b LABELS cpython llvm llvm_jit c) +# RUN(NAME global_syms_03_c LABELS cpython llvm llvm_jit c) +# RUN(NAME global_syms_04 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME global_syms_05 LABELS cpython llvm llvm_jit c) +RUN(NAME global_syms_06 LABELS cpython llvm llvm_jit c) + +RUN(NAME callback_01 LABELS cpython llvm llvm_jit c) +RUN(NAME callback_02 LABELS cpython llvm llvm_jit c) +RUN(NAME callback_03 LABELS cpython llvm llvm_jit c) + +RUN(NAME lambda_01 LABELS cpython llvm llvm_jit) + +RUN(NAME c_mangling LABELS cpython llvm llvm_jit) # renable c +# RUN(NAME class_01 LABELS cpython llvm llvm_jit) +# RUN(NAME class_02 LABELS cpython llvm llvm_jit) +# RUN(NAME class_03 LABELS cpython llvm llvm_jit) +# RUN(NAME class_04 LABELS cpython llvm llvm_jit) +# RUN(NAME class_05 LABELS cpython llvm llvm_jit) +# RUN(NAME class_06 LABELS cpython llvm llvm_jit) + + +# callback_04 is to test emulation. So just run with cpython +RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython) + +# Intrinsic Functions +RUN(NAME intrinsics_01 LABELS cpython llvm llvm_jit NOFAST) # any +RUN(NAME intrinsics_02 LABELS cpython llvm llvm_jit c) # floordiv +# RUN(NAME test_builtin_type LABELS cpython llvm llvm_jit c) # type +# RUN(NAME test_builtin_type_set LABELS cpython llvm llvm_jit) # type (specifically for `set`) + +# lpython decorator +# RUN(NAME lpython_decorator_01 LABELS cpython) +# RUN(NAME lpython_decorator_02 LABELS cpython) + +COMPILE(NAME import_order_01 LABELS cpython llvm llvm_jit c) # any + +# LPython emulation mode +RUN(NAME lpython_emulation_01 LABELS cpython NOMOD) diff --git a/integration_tests/array_01.py b/integration_tests/array_01.py index 779b3934e1..c492d6b31c 100644 --- a/integration_tests/array_01.py +++ b/integration_tests/array_01.py @@ -1,9 +1,9 @@ -from ltypes import i32 -from numpy import empty +from lpython import i32 +from numpy import empty, int32 def main0(): Nx: i32 = 600; Ny: i32 = 450 - arr: i32[450, 600] = empty([Ny, Nx]) + arr: i32[450, 600] = empty([450, 600], dtype=int32) i: i32 j: i32 for i in range(Ny): diff --git a/integration_tests/array_01_decl.py b/integration_tests/array_01_decl.py index 52812a030a..153f7c9557 100644 --- a/integration_tests/array_01_decl.py +++ b/integration_tests/array_01_decl.py @@ -1,4 +1,4 @@ -from ltypes import i16, i32, i64, f32, f64, c32, c64 +from lpython import i16, i32, i64, f32, f64, c32, c64 from numpy import empty, int16, int32, int64, float32, float64, complex64, complex128 from enum import Enum diff --git a/integration_tests/array_02.py b/integration_tests/array_02.py index 6e3c7bca7d..6c9c2ea5c2 100644 --- a/integration_tests/array_02.py +++ b/integration_tests/array_02.py @@ -1,9 +1,9 @@ -from ltypes import i32 -from numpy import empty +from lpython import i32 +from numpy import empty, int32 def main0(): Nx: i32 = 60; Ny: i32 = 45; Nz: i32 = 20 - arr: i32[45, 60, 20] = empty([Ny, Nx, Nz]) + arr: i32[45, 60, 20] = empty([45, 60, 20], dtype=int32) i: i32 j: i32 k: i32 diff --git a/integration_tests/array_02_decl.py b/integration_tests/array_02_decl.py index 5969ba8a85..1f5c07d76c 100644 --- a/integration_tests/array_02_decl.py +++ b/integration_tests/array_02_decl.py @@ -1,5 +1,5 @@ -from ltypes import i32, i64, f32, f64, c32, c64 -from numpy import empty +from lpython import i32, i64, f32, f64, c32, c64 +from numpy import empty, int32, int64, float32, float64, complex64, complex128 def accept_multidim_i32_array(xi32: i32[:, :]) -> i32: return xi32[0, 0] @@ -14,12 +14,12 @@ def accept_multidim_f64_array(xf64: f64[:, :]) -> f64: return xf64[0, 1] def declare_arrays(): - ai32: i32[3, 3] = empty([3, 3]) - ai64: i64[10, 10, 10] = empty([10, 10, 10]) - af32: f32[3] = empty(3) - af64: f64[10, 4] = empty([10, 4]) - ac32: c32[3, 5, 99] = empty([3, 5, 99]) - ac64: c64[10, 13, 11, 16] = empty([10, 13, 11, 16]) + ai32: i32[3, 3] = empty([3, 3], dtype=int32) + ai64: i64[10, 10, 10] = empty([10, 10, 10], dtype=int64) + af32: f32[3] = empty(3, dtype=float32) + af64: f64[10, 4] = empty([10, 4], dtype=float64) + ac32: c32[3, 5, 99] = empty([3, 5, 99], dtype=complex64) + ac64: c64[10, 13, 11, 16] = empty([10, 13, 11, 16], dtype=complex128) print(accept_multidim_i32_array(ai32)) print(accept_multidim_i64_array(ai64)) print(accept_multidim_f32_array(af32)) diff --git a/integration_tests/array_03.py b/integration_tests/array_03.py new file mode 100644 index 0000000000..975fe4aea6 --- /dev/null +++ b/integration_tests/array_03.py @@ -0,0 +1,20 @@ +from lpython import Allocatable, f64, i32 +from numpy import empty, float64, int32 + +def f(): + n: i32 = 5 + a: Allocatable[f64[:]] = empty((n,), dtype=float64) + i: i32 + for i in range(n): + a[i] = f64(i+1) + for i in range(n): + assert abs(a[i] - f64(i + 1)) < 1e-12 + b: Allocatable[i32[:]] + n = 10 + b = empty((n,), dtype=int32) + for i in range(n): + b[i] = i+1 + for i in range(n): + assert b[i] == i+1 + +f() diff --git a/integration_tests/array_03_decl.py b/integration_tests/array_03_decl.py index 7b38806fc4..9fb02782ca 100644 --- a/integration_tests/array_03_decl.py +++ b/integration_tests/array_03_decl.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, dataclass +from lpython import i32, f64, dataclass from numpy import empty @dataclass @@ -12,8 +12,8 @@ class Truck: wheels: i32 def declare_struct_array(): - cars: Car[1] = empty(10, dtype=Car) - trucks: Truck[2] = empty(20, dtype=Truck) + cars: Car[1] = empty(1, dtype=Car) + trucks: Truck[2] = empty(2, dtype=Truck) cars[0] = Car(100000, 800.0) trucks[0] = Truck(1000000, 8) trucks[1] = Truck(5000000, 12) diff --git a/integration_tests/array_04.py b/integration_tests/array_04.py new file mode 100644 index 0000000000..c7cd24ae4a --- /dev/null +++ b/integration_tests/array_04.py @@ -0,0 +1,19 @@ +from lpython import i32, Const +from numpy import empty, int32 + +def main0(): + n: Const[i32] = 1 + x: i32[n, n] = empty([n, n], dtype=int32) + y: i32[n, n] = empty([n, n], dtype=int32) + + x[0, 0] = -10 + y[0, 0] = -10 + + print(x[0, 0], y[0, 0]) + assert x == y + + y[0, 0] = 10 + print(x[0, 0], y[0, 0]) + assert x != y + +main0() diff --git a/integration_tests/array_05.py b/integration_tests/array_05.py new file mode 100644 index 0000000000..4c18576cac --- /dev/null +++ b/integration_tests/array_05.py @@ -0,0 +1,39 @@ +from lpython import i32, f64, Array +from numpy import empty, int32, float64 + + +def test_1(): + y: Array[f64, 3] = empty([3], dtype=float64) + y[0] = 3.14 + y[1] = -4.14 + y[2] = 100.100 + + print(y) + assert abs(y[0] - (3.14)) <= 1e-6 + assert abs(y[1] - (-4.14)) <= 1e-6 + assert abs(y[2] - (100.100)) <= 1e-6 + +def test_2(): + x: Array[i32, 2, 3] = empty([2, 3], dtype=int32) + + x[0, 0] = 5 + x[0, 1] = -10 + x[0, 2] = 15 + x[1, 0] = 4 + x[1, 1] = -14 + x[1, 2] = 100 + + print(x) + assert x[0, 0] == 5 + assert x[0, 1] == -10 + assert x[0, 2] == 15 + assert x[1, 0] == 4 + assert x[1, 1] == -14 + assert x[1, 2] == 100 + + +def main0(): + test_1() + test_2() + +main0() diff --git a/integration_tests/array_06.py b/integration_tests/array_06.py new file mode 100644 index 0000000000..b44d4ed347 --- /dev/null +++ b/integration_tests/array_06.py @@ -0,0 +1,19 @@ +from numpy import empty, int16 +from lpython import i16, i32, Const + +def spot_print_lpython_array(a: i16[:,:]) -> None: + print(a) + +def main() -> i32: + n : Const[i32] = 15 + m : Const[i32] = 3 + Anm: i16[n, m] = empty((n,m), dtype=int16) + i: i32; j: i32 + for i in range(n): + for j in range(m): + Anm[i,j] = i16(5) + spot_print_lpython_array(Anm) + return 0 + +if __name__ == "__main__": + main() diff --git a/integration_tests/array_expr_01.py b/integration_tests/array_expr_01.py index 8890fd621f..0136710c93 100644 --- a/integration_tests/array_expr_01.py +++ b/integration_tests/array_expr_01.py @@ -1,22 +1,18 @@ -from ltypes import i32, f32, f64 +from lpython import Const, i32, f32, f64 from numpy import empty, reshape, int32, float64 def array_expr_01(): - dim1: i32 - dim2: i32 - dim3: i32 - dim1d: i32 + dim1: Const[i32] = 10 + dim2: Const[i32] = 10 + dim3: Const[i32] = 5 + dim1d: Const[i32] = dim1 * dim2 * dim3 + i: i32 shape1d: i32[1] = empty(1, dtype=int32) shape3d: i32[3] = empty(3, dtype=int32) eps: f64 eps = 1e-12 - dim1 = 10 - dim2 = 10 - dim3 = 5 - dim1d = dim1 * dim2 * dim3 - e: f64[10, 10, 5] = empty((dim1, dim2, dim3), dtype=float64) f: f64[10, 10, 5] = empty((dim1, dim2, dim3), dtype=float64) g: f64[500] = empty(dim1d, dtype=float64) diff --git a/integration_tests/array_expr_02.py b/integration_tests/array_expr_02.py index 332a223653..28fbe6b38a 100644 --- a/integration_tests/array_expr_02.py +++ b/integration_tests/array_expr_02.py @@ -1,7 +1,6 @@ -from ltypes import i32, f32, TypeVar +from lpython import i32, f32, TypeVar from numpy import empty, sqrt, float32 -n: i32 n = TypeVar("n") def modify(array_a: f32[:], n: i32) -> f32[n]: diff --git a/integration_tests/array_expr_03.py b/integration_tests/array_expr_03.py new file mode 100644 index 0000000000..f0af73a57b --- /dev/null +++ b/integration_tests/array_expr_03.py @@ -0,0 +1,24 @@ +from lpython import i8, i32, dataclass, field +from numpy import empty, int8, array + + +@dataclass +class LPBHV_small: + dim: i32 = 4 + a: i8[4] = field(default_factory=lambda: empty(4, dtype=int8)) + + +def g(): + l2: LPBHV_small = LPBHV_small(4, array([127, -127, 3, 111], dtype=int8)) + + print(l2.dim) + assert l2.dim == 4 + + print(l2.a[0], l2.a[1], l2.a[2], l2.a[3]) + assert l2.a[0] == i8(127) + assert l2.a[1] == i8(-127) + assert l2.a[2] == i8(3) + assert l2.a[3] == i8(111) + + +g() diff --git a/integration_tests/array_expr_04.py b/integration_tests/array_expr_04.py new file mode 100644 index 0000000000..c14e4cc988 --- /dev/null +++ b/integration_tests/array_expr_04.py @@ -0,0 +1,35 @@ +from lpython import i8, i16, i32, i64 +from numpy import int8, int16, int32, int64, array + +def g(): + a8: i8[4] = array([127, -127, 3, 111], dtype=int8) + a16: i16[4] = array([127, -127, 3, 111], dtype=int16) + a32: i32[4] = array([127, -127, 3, 111], dtype=int32) + a64: i64[4] = array([127, -127, 3, 111], dtype=int64) + + print(a8) + print(a16) + print(a32) + print(a64) + + assert (a8[0] == i8(127)) + assert (a8[1] == i8(-127)) + assert (a8[2] == i8(3)) + assert (a8[3] == i8(111)) + + assert (a16[0] == i16(127)) + assert (a16[1] == i16(-127)) + assert (a16[2] == i16(3)) + assert (a16[3] == i16(111)) + + assert (a32[0] == i32(127)) + assert (a32[1] == i32(-127)) + assert (a32[2] == i32(3)) + assert (a32[3] == i32(111)) + + assert (a64[0] == i64(127)) + assert (a64[1] == i64(-127)) + assert (a64[2] == i64(3)) + assert (a64[3] == i64(111)) + +g() diff --git a/integration_tests/array_expr_05.py b/integration_tests/array_expr_05.py new file mode 100644 index 0000000000..7a7beeb1ae --- /dev/null +++ b/integration_tests/array_expr_05.py @@ -0,0 +1,31 @@ +from lpython import u8, u16, u32, u64, i8 +from numpy import uint8, uint16, uint32, uint64, array + +def g(): + a8: u8[3] = array([127, 3, 111], dtype=uint8) + a16: u16[3] = array([127, 3, 111], dtype=uint16) + a32: u32[3] = array([127, 3, 111], dtype=uint32) + a64: u64[3] = array([127, 3, 111], dtype=uint64) + + assert (a8[0] == u8(127)) + assert (a8[1] == u8(3)) + assert (a8[2] == u8(111)) + + assert (a16[0] == u16(127)) + assert (a16[1] == u16(3)) + assert (a16[2] == u16(111)) + + assert (a32[0] == u32(127)) + assert (a32[1] == u32(3)) + assert (a32[2] == u32(111)) + + assert (a64[0] == u64(127)) + assert (a64[1] == u64(3)) + assert (a64[2] == u64(111)) + + print(a8) + print(a16) + print(a32) + print(a64) + +g() diff --git a/integration_tests/array_expr_06.py b/integration_tests/array_expr_06.py new file mode 100644 index 0000000000..b6dc397d87 --- /dev/null +++ b/integration_tests/array_expr_06.py @@ -0,0 +1,21 @@ +from lpython import f32, f64 +from numpy import float32, float64, array + +def g(): + a32: f32[4] = array([127, -127, 3, 111], dtype=float32) + a64: f64[4] = array([127, -127, 3, 111], dtype=float64) + + print(a32) + print(a64) + + assert (abs(a32[0] - f32(127)) <= f32(1e-5)) + assert (abs(a32[1] - f32(-127)) <= f32(1e-5)) + assert (abs(a32[2] - f32(3)) <= f32(1e-5)) + assert (abs(a32[3] - f32(111)) <= f32(1e-5)) + + assert (abs(a64[0] - f64(127)) <= 1e-5) + assert (abs(a64[1] - f64(-127)) <= 1e-5) + assert (abs(a64[2] - f64(3)) <= 1e-5) + assert (abs(a64[3] - f64(111)) <= 1e-5) + +g() diff --git a/integration_tests/array_expr_07.py b/integration_tests/array_expr_07.py new file mode 100644 index 0000000000..598a7fcb64 --- /dev/null +++ b/integration_tests/array_expr_07.py @@ -0,0 +1,21 @@ +from lpython import c32, c64, f32 +from numpy import complex64, complex128, array + +def g(): + a32: c32[4] = array([127, -127, 3, 111], dtype=complex64) + a64: c64[4] = array([127, -127, 3, 111], dtype=complex128) + + print(a32) + print(a64) + + assert (abs(a32[0] - c32(127)) <= f32(1e-5)) + assert (abs(a32[1] - c32(-127)) <= f32(1e-5)) + assert (abs(a32[2] - c32(3)) <= f32(1e-5)) + assert (abs(a32[3] - c32(111)) <= f32(1e-5)) + + assert (abs(a64[0] - c64(127)) <= 1e-5) + assert (abs(a64[1] - c64(-127)) <= 1e-5) + assert (abs(a64[2] - c64(3)) <= 1e-5) + assert (abs(a64[3] - c64(111)) <= 1e-5) + +g() diff --git a/integration_tests/array_expr_08.py b/integration_tests/array_expr_08.py new file mode 100644 index 0000000000..ba0cf0dcb7 --- /dev/null +++ b/integration_tests/array_expr_08.py @@ -0,0 +1,14 @@ +from lpython import i1 +from numpy import bool_, array + +def g(): + a1: i1[4] = array([0, -127, 0, 111], dtype=bool_) + + print(a1) + + assert not a1[0] + assert a1[1] + assert not a1[2] + assert a1[3] + +g() diff --git a/integration_tests/array_expr_09.py b/integration_tests/array_expr_09.py new file mode 100644 index 0000000000..3590f65ca3 --- /dev/null +++ b/integration_tests/array_expr_09.py @@ -0,0 +1,23 @@ +from lpython import (i32, Const) +from numpy import empty, int32 + +dim: Const[i32] = 2 +dim2: Const[i32] = 3 + +def g(): + a: i32[dim, dim2] = empty((dim, dim2), dtype=int32) + i1: i32 = 0 + i2: i32 = 0 + for i1 in range(dim): + for i2 in range(dim2): + a[i1, i2] = i32(i1 * dim2 + i2) + # a: [[0, 1, 2], [3, 4, 5]] + print(a) + assert a[-1, -1] == 5 + assert a[-1, -2] == 4 + assert a[-1, -3] == 3 + assert a[-2, -1] == 2 + assert a[-2, -2] == 1 + assert a[-2, -3] == 0 + +g() \ No newline at end of file diff --git a/integration_tests/array_expr_10.py b/integration_tests/array_expr_10.py new file mode 100644 index 0000000000..3681702818 --- /dev/null +++ b/integration_tests/array_expr_10.py @@ -0,0 +1,17 @@ +from lpython import i32 +from numpy import empty, int32, array + +def foo(x: i32[:]): + print(x[3], x[4], x[-1], x[-2]) + assert x[-1] == 5 + assert x[-2] == 4 + assert x[-3] == 3 + assert x[-4] == 2 + assert x[-5] == 1 + +def main(): + x: i32[5] = empty(5, dtype=int32) + x = array([1, 2, 3, 4, 5]) + foo(x) + +main() \ No newline at end of file diff --git a/integration_tests/array_size_01.py b/integration_tests/array_size_01.py new file mode 100644 index 0000000000..17135ee098 --- /dev/null +++ b/integration_tests/array_size_01.py @@ -0,0 +1,23 @@ +from lpython import i32, f64, c32, c64 +from numpy import empty, int32, float64, complex64, complex128 + +def main0(): + x: i32[4, 5, 2] = empty([4, 5, 2], dtype=int32) + y: f64[24, 100, 2, 5] = empty([24, 100, 2, 5], dtype=float64) + print(x.size) + print(y.size) + + assert x.size == 40 + assert y.size == 24000 + +def main1(): + a: c32[12] = empty([12], dtype=complex64) + b: c64[15, 15, 10] = empty([15, 15, 10], dtype=complex128) + print(a.size) + print(b.size) + + assert a.size == 12 + assert b.size == 2250 + +main0() +main1() diff --git a/integration_tests/array_size_02.py b/integration_tests/array_size_02.py new file mode 100644 index 0000000000..1d238926fd --- /dev/null +++ b/integration_tests/array_size_02.py @@ -0,0 +1,90 @@ +from lpython import i32, f64, c32, c64, u32, u64 +from numpy import empty, size, int32, uint32, uint64, float64, complex64, complex128 + +def main0(): + x: i32[4, 5, 2] = empty([4, 5, 2], dtype=int32) + y: f64[24, 100, 2, 5] = empty([24, 100, 2, 5], dtype=float64) + z: i32 + w: i32 + z = 2 + w = 3 + print(size(x)) + print(size(x, 0)) + print(size(x, 1)) + print(size(x, 2)) + print(size(y)) + print(size(y, 0)) + print(size(y, 1)) + print(size(y, z)) + print(size(y, w)) + + assert size(x) == 40 + assert size(x, 0) == 4 + assert size(x, 1) == 5 + assert size(x, 2) == 2 + assert size(y) == 24000 + assert size(y, 0) == 24 + assert size(y, 1) == 100 + assert size(y, z) == 2 + assert size(y, w) == 5 + +def main1(): + a: c32[12] = empty([12], dtype=complex64) + b: c64[15, 15, 10] = empty([15, 15, 10], dtype=complex128) + c: i32 + d: i32 + c = 1 + d = 2 + print(size(a)) + print(size(a, 0)) + print(size(b)) + print(size(b, 0)) + print(size(b, c)) + print(size(b, d)) + + assert size(a) == 12 + assert size(a, 0) == 12 + assert size(b) == 2250 + assert size(b, 0) == 15 + assert size(b, c) == 15 + assert size(b, d) == 10 + +def main2(): + a: i32[2, 3] = empty([2, 3], dtype=int32) + print(size(a)) + print(size(a, 0)) + print(size(a, 1)) + + assert size(a) == 2*3 + assert size(a, 0) == 2 + assert size(a, 1) == 3 + +def main3(): + a: u32[2, 3, 4] = empty([2, 3, 4], dtype=uint32) + b: u64[10, 5] = empty([10, 5], dtype=uint64) + c: i32 + d: i32 + c = 1 + d = 2 + print(size(a)) + print(size(a, 0)) + print(size(a, c)) + print(size(a, d)) + + print(size(b)) + print(size(b, 0)) + print(size(b, c)) + + assert size(a) == 2*3*4 + assert size(a, 0) == 2 + assert size(a, c) == 3 + assert size(a, d) == 4 + + assert size(b) == 50 + assert size(b, 0) == 10 + assert size(b, c) == 5 + +main0() +main1() +main2() +main3() diff --git a/integration_tests/bindc_01.py b/integration_tests/bindc_01.py index 5c758339e5..6b83811264 100644 --- a/integration_tests/bindc_01.py +++ b/integration_tests/bindc_01.py @@ -1,5 +1,14 @@ -from ltypes import c_p_pointer, CPtr, i16, Pointer, empty_c_void_p +from lpython import c_p_pointer, CPtr, i16, Pointer, empty_c_void_p queries: CPtr = empty_c_void_p() x: Pointer[i16] = c_p_pointer(queries, i16) print(queries, x) + + +def test_issue_1781(): + p: CPtr = empty_c_void_p() + assert p == empty_c_void_p() + assert not (p != empty_c_void_p()) + + +test_issue_1781() diff --git a/integration_tests/bindc_02.py b/integration_tests/bindc_02.py index 0ad7845489..58f0ad1290 100644 --- a/integration_tests/bindc_02.py +++ b/integration_tests/bindc_02.py @@ -1,8 +1,8 @@ -from ltypes import c_p_pointer, CPtr, pointer, i16, Pointer, empty_c_void_p -from numpy import empty, int16 +from lpython import c_p_pointer, CPtr, pointer, i16, Pointer, empty_c_void_p +from numpy import empty, int16, array queries: CPtr = empty_c_void_p() -x: Pointer[i16[:]] = c_p_pointer(queries, i16[:]) +x: Pointer[i16[:]] = c_p_pointer(queries, i16[:], array([1])) print(queries, x) def f(): @@ -17,8 +17,8 @@ def f(): assert yptr1[0] == i16(1) assert yptr1[1] == i16(2) - yptr1 = c_p_pointer(yq, i16[:]) + yptr1 = c_p_pointer(yq, i16[:], array([2])) - print(yq, yptr1) + # print(yq, yptr1) f() diff --git a/integration_tests/bindc_03.py b/integration_tests/bindc_03.py index 1138522b09..59b1f0efbc 100644 --- a/integration_tests/bindc_03.py +++ b/integration_tests/bindc_03.py @@ -1,17 +1,21 @@ -from ltypes import c_p_pointer, CPtr, pointer, i32, Pointer, ccall, p_c_pointer, dataclass +from lpython import (c_p_pointer, CPtr, pointer, i32, + Pointer, ccall, p_c_pointer, dataclass, + ccallable, empty_c_void_p, cptr_to_u64, + u64_to_cptr, u64) +from numpy import array @dataclass class ArrayWrapped: array: CPtr -@ccall +@ccall(header="bindc_03b.h") def g(a: CPtr, value: i32, offset_value: bool) -> None: pass def gpy(a: CPtr, value: i32, offset_value: bool) -> None: g(a, value, offset_value) -@ccall +@ccall(header="bindc_03b.h") def get_array(size: i32) -> CPtr: pass @@ -19,7 +23,7 @@ def get_array(size: i32) -> CPtr: def f(q_void: CPtr) -> None: i: i32 el: i32 - q: Pointer[i32[:]] = c_p_pointer(q_void, i32[:]) + q: Pointer[i32[:]] = c_p_pointer(q_void, i32[:], array([10])) for i in range(10): q2: CPtr p_c_pointer(pointer(q[i]), q2) @@ -32,23 +36,38 @@ def f(q_void: CPtr) -> None: def h(q_void: CPtr) -> None: i: i32 el: i32 - q: Pointer[i32[:]] = c_p_pointer(q_void, i32[:]) + q: Pointer[i32[:]] = c_p_pointer(q_void, i32[:], array([10])) for i in range(10): # TODO: Use q[i] directly in the assert. el = q[i] print(el) assert el == i * i + i%2 + +@ccallable(header="_test_bindc_03_my_header.h") +def test_emit_header_ccallable() -> i32: + i: i32 = 5 + assert i == 5 + i = i*5 + return i + 10 + def run(): a: CPtr array_wrapped: ArrayWrapped = ArrayWrapped(a) - array_wrapped1: ArrayWrapped + array_wrapped1: ArrayWrapped = ArrayWrapped() size: i32 size = 10 a = get_array(size) + assert a != empty_c_void_p() array_wrapped.array = a f(array_wrapped.array) + q: u64 = cptr_to_u64(a) + x: CPtr + x = u64_to_cptr(q) + array_wrapped.array = x + f(array_wrapped.array) array_wrapped1 = array_wrapped h(array_wrapped1.array) + assert test_emit_header_ccallable() == 35 run() diff --git a/integration_tests/bindc_04.py b/integration_tests/bindc_04.py index 1956c68c8c..0589fcee66 100644 --- a/integration_tests/bindc_04.py +++ b/integration_tests/bindc_04.py @@ -1,4 +1,4 @@ -from ltypes import pointer, i16, Pointer +from lpython import pointer, i16, Pointer # Testing Global Pointers x: Pointer[i16[:]] diff --git a/integration_tests/bindc_05.py b/integration_tests/bindc_05.py index ee936ab364..b01ceee8ba 100644 --- a/integration_tests/bindc_05.py +++ b/integration_tests/bindc_05.py @@ -1,14 +1,14 @@ -from ltypes import CPtr, empty_c_void_p, i32, f32, dataclass, Pointer, ccall, p_c_pointer, pointer +from lpython import CPtr, empty_c_void_p, i32, f32, dataclass, Pointer, ccall, p_c_pointer, pointer @dataclass class Void: data: CPtr -@ccall +@ccall(header="bindc_05b.h") def trunc_custom(value: Pointer[CPtr]) -> CPtr: pass -@ccall +@ccall(header="bindc_05b.h") def print_value(value: CPtr): pass diff --git a/integration_tests/bindc_05b.h b/integration_tests/bindc_05b.h index b4533c4320..95d372053c 100644 --- a/integration_tests/bindc_05b.h +++ b/integration_tests/bindc_05b.h @@ -1,2 +1,7 @@ +#ifndef BINDC_05BH +#define BINDC_05BH + void* trunc_custom(void** value); void print_value(float* value); + +#endif // BINDC_05BH diff --git a/integration_tests/bindc_06.py b/integration_tests/bindc_06.py index a80e1b5c4a..d01ca9b800 100644 --- a/integration_tests/bindc_06.py +++ b/integration_tests/bindc_06.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, ccall, dataclass +from lpython import i32, f64, ccall, dataclass from numpy import empty, int32, float64 @dataclass @@ -6,7 +6,7 @@ class CompareOperator: op_code: i32 op_name: str -@ccall +@ccall(header="bindc_06b.h") def compare_array_element(value1: i32, value2: f64, op: i32) -> i32: pass diff --git a/integration_tests/bindc_06b.h b/integration_tests/bindc_06b.h index 0e5fac7de4..680d387c7f 100644 --- a/integration_tests/bindc_06b.h +++ b/integration_tests/bindc_06b.h @@ -1,3 +1,8 @@ +#ifndef BINDC_06BH +#define BINDC_06BH + #include int32_t compare_array_element(int32_t value1, double value2, int32_t code); + +#endif // BINDC_06BH diff --git a/integration_tests/bindc_07.py b/integration_tests/bindc_07.py index 038a2d659b..f03af3331b 100644 --- a/integration_tests/bindc_07.py +++ b/integration_tests/bindc_07.py @@ -1,24 +1,37 @@ -from ltypes import CPtr, i64, sizeof, i32, i16, i8, ccall, c_p_pointer, empty_c_void_p, Pointer, pointer -from numpy import empty, int64 +from lpython import (CPtr, sizeof, ccall, c_p_pointer, empty_c_void_p, + i64, i32, i16, i8, + u64, u32, u16, u8, + Pointer, pointer, u16) +from numpy import array @ccall def _lfortran_malloc(size: i32) -> CPtr: pass -def allocate_memory(size: i32) -> tuple[CPtr, CPtr, CPtr, CPtr]: +def allocate_memory(size: i32) -> tuple[CPtr, CPtr, CPtr, CPtr, \ + CPtr, CPtr, CPtr, CPtr]: array1: CPtr = _lfortran_malloc(size * i32(sizeof(i8))) array2: CPtr = _lfortran_malloc(size * i32(sizeof(i16))) array3: CPtr = _lfortran_malloc(size * i32(sizeof(i32))) array4: CPtr = _lfortran_malloc(size * i32(sizeof(i64))) - return array1, array2, array3, array4 + array5: CPtr = _lfortran_malloc(size * i32(sizeof(u8))) + array6: CPtr = _lfortran_malloc(size * i32(sizeof(u16))) + array7: CPtr = _lfortran_malloc(size * i32(sizeof(u32))) + array8: CPtr = _lfortran_malloc(size * i32(sizeof(u64))) + return array1, array2, array3, array4, array5, array6, array7, array8 -def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, size: i32): - iarray1: Pointer[i8[size]] = c_p_pointer(array1, i8[size]) - iarray2: Pointer[i16[size]] = c_p_pointer(array2, i16[size]) - iarray3: Pointer[i32[size]] = c_p_pointer(array3, i32[size]) - iarray4: Pointer[i64[size]] = c_p_pointer(array4, i64[size]) +def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, \ + array5: CPtr, array6: CPtr, array7: CPtr, array8: CPtr, size: i32): + iarray1: Pointer[i8[:]] = c_p_pointer(array1, i8[:], array([size])) + iarray2: Pointer[i16[:]] = c_p_pointer(array2, i16[:], array([size])) + iarray3: Pointer[i32[:]] = c_p_pointer(array3, i32[:], array([size])) + iarray4: Pointer[i64[:]] = c_p_pointer(array4, i64[:], array([size])) + iarray5: Pointer[u8[:]] = c_p_pointer(array5, u8[:], array([size])) + iarray6: Pointer[u16[:]] = c_p_pointer(array6, u16[:], array([size])) + iarray7: Pointer[u32[:]] = c_p_pointer(array7, u32[:], array([size])) + iarray8: Pointer[u64[:]] = c_p_pointer(array8, u64[:], array([size])) sum_array_cptr: CPtr = _lfortran_malloc(size * i32(sizeof(i64))) - sum_array: Pointer[i64[size]] = c_p_pointer(sum_array_cptr, i64[size]) + sum_array: Pointer[i64[:]] = c_p_pointer(sum_array_cptr, i64[:], array([size])) i: i32 for i in range(size): @@ -26,20 +39,30 @@ def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, size: i32 iarray2[i] = i16(2 * i) iarray3[i] = i32(3 * i) iarray4[i] = i64(4 * i) + iarray5[i] = u8(i) + iarray6[i] = u16(6 * i) + iarray7[i] = u32(7 * i) + iarray8[i] = u64(8 * i) for i in range(size): - sum_array[i] = i64(iarray1[i]) + i64(iarray2[i]) + i64(iarray3[i]) + iarray4[i] + sum_array[i] = i64(iarray1[i]) + i64(iarray2[i]) + i64(iarray3[i]) \ + + iarray4[i] + i64(iarray5[i]) + i64(iarray6[i]) \ + + i64(iarray7[i]) + i64(iarray8[i]) for i in range(size): print(i, sum_array[i]) - assert sum_array[i] == i64(10 * i) + assert sum_array[i] == i64(32 * i) def test_tuple_return(): a: CPtr = empty_c_void_p() b: CPtr = empty_c_void_p() c: CPtr = empty_c_void_p() d: CPtr = empty_c_void_p() - a, b, c, d = allocate_memory(50) - sum_arrays(a, b, c, d, 50) + e: CPtr = empty_c_void_p() + f: CPtr = empty_c_void_p() + g: CPtr = empty_c_void_p() + h: CPtr = empty_c_void_p() + a, b, c, d, e, f, g, h = allocate_memory(50) + sum_arrays(a, b, c, d, e, f, g, h, 50) test_tuple_return() diff --git a/integration_tests/bindc_08.py b/integration_tests/bindc_08.py new file mode 100644 index 0000000000..e23e979b80 --- /dev/null +++ b/integration_tests/bindc_08.py @@ -0,0 +1,26 @@ +# file: main.py +from lpython import CPtr, i32, dataclass, c_p_pointer, Pointer, empty_c_void_p, p_c_pointer, Array + +from numpy import empty, array + +@dataclass +class Foo: + x: i32 + y: i32 + +def init(foos_ptr: CPtr) -> None: + foos: Pointer[Array[Foo, :]] = c_p_pointer(foos_ptr, Array[Foo, :], array([1])) + foos[0] = Foo(3, 2) + +def main() -> None: + foos: Array[Foo, 1] = empty(1, dtype=Foo) + foos_ptr: CPtr = empty_c_void_p() + foos[0] = Foo(0, 1) + p_c_pointer(foos, foos_ptr) + init(foos_ptr) + print("foos[0].x = ", foos[0].x) + print("foos[0].y = ", foos[0].y) + assert foos[0].x == 3 + assert foos[0].y == 2 + +main() diff --git a/integration_tests/bindc_09.py b/integration_tests/bindc_09.py new file mode 100644 index 0000000000..956b56b658 --- /dev/null +++ b/integration_tests/bindc_09.py @@ -0,0 +1,42 @@ +from enum import Enum + +from lpython import (CPtr, c_p_pointer, p_c_pointer, dataclass, empty_c_void_p, + pointer, Pointer, i32, ccallable, InOut) + +class Value(Enum): + TEN: i32 = 10 + TWO: i32 = 2 + ONE: i32 = 1 + FIVE: i32 = 5 + +@dataclass +class Foo: + value: Value + +@ccallable +@dataclass +class FooC: + value: Value + +def bar(foo: InOut[Foo]) -> None: + foo.value = Value.FIVE + +def barc(foo_ptr: CPtr) -> None: + foo: Pointer[FooC] = c_p_pointer(foo_ptr, FooC) + foo.value = Value.ONE + +def main() -> None: + foo: Foo = Foo(Value.TEN) + fooc: FooC = FooC(Value.TWO) + foo_ptr: CPtr = empty_c_void_p() + + bar(foo) + print(foo.value, foo.value.name) + assert foo.value == Value.FIVE + + p_c_pointer(pointer(fooc), foo_ptr) + barc(foo_ptr) + print(fooc.value) + assert fooc.value == Value.ONE.value + +main() diff --git a/integration_tests/bindc_09b.py b/integration_tests/bindc_09b.py new file mode 100644 index 0000000000..58be1e768b --- /dev/null +++ b/integration_tests/bindc_09b.py @@ -0,0 +1,44 @@ +from enum import Enum + +from lpython import CPtr, c_p_pointer, p_c_pointer, dataclass, empty_c_void_p, pointer, Pointer, i32, ccallable + +class Value(Enum): + TEN: i32 = 10 + TWO: i32 = 2 + ONE: i32 = 1 + FIVE: i32 = 5 + +@ccallable +@dataclass +class Foo: + value: Value + +@ccallable +@dataclass +class FooC: + value: Value + +def bar(foo_ptr: CPtr) -> None: + foo: Pointer[Foo] = c_p_pointer(foo_ptr, Foo) + foo.value = Value.FIVE + +def barc(foo_ptr: CPtr) -> None: + foo: Pointer[FooC] = c_p_pointer(foo_ptr, FooC) + foo.value = Value.ONE + +def main() -> None: + foo: Foo = Foo(Value.TEN) + fooc: FooC = FooC(Value.TWO) + foo_ptr: CPtr = empty_c_void_p() + + p_c_pointer(pointer(foo), foo_ptr) + bar(foo_ptr) + print(foo.value) + assert foo.value == Value.FIVE.value + + p_c_pointer(pointer(fooc), foo_ptr) + barc(foo_ptr) + print(fooc.value) + assert fooc.value == Value.ONE.value + +main() diff --git a/integration_tests/bindc_10.py b/integration_tests/bindc_10.py new file mode 100644 index 0000000000..934eacfd43 --- /dev/null +++ b/integration_tests/bindc_10.py @@ -0,0 +1,32 @@ +from lpython import (i64, i16, CPtr, c_p_pointer, Pointer, sizeof, packed, + dataclass, ccallable, ccall, i32) + +@ccall +def _lfortran_malloc(size: i32) -> CPtr: + pass + + +def alloc(buf_size:i64) -> CPtr: + return _lfortran_malloc(i32(buf_size)) + + +@ccallable +@packed +@dataclass +class S: + a: i16 + b: i64 + + +def main(): + p1: CPtr = alloc(sizeof(S)) + print(p1) + p2: Pointer[S] = c_p_pointer(p1, S) + p2.a = i16(5) + p2.b = i64(4) + print(p2.a, p2.b) + assert p2.a == i16(5) + assert p2.b == i64(4) + + +main() diff --git a/integration_tests/bindc_11.py b/integration_tests/bindc_11.py new file mode 100644 index 0000000000..c2e81c9a0a --- /dev/null +++ b/integration_tests/bindc_11.py @@ -0,0 +1,34 @@ +import numpy, ctypes +from lpython import (i64, i16, CPtr, c_p_pointer, Pointer, sizeof, packed, + dataclass, ccallable, ccall, i32) + +global_arrays = [] + + +def alloc(buf_size:i64) -> CPtr: + xs = numpy.empty(buf_size, dtype=numpy.uint8) + global_arrays.append(xs) + p = ctypes.c_void_p(xs.ctypes.data) + return ctypes.cast(p.value, ctypes.c_void_p) + + +@ccallable +@packed +@dataclass +class S: + a: i16 + b: i64 + + +def main(): + p1: CPtr = alloc(sizeof(S)) + print(p1) + p2: Pointer[S] = c_p_pointer(p1, S) + p2.a = i16(5) + p2.b = i64(4) + print(p2.a, p2.b) + assert p2.a == i16(5) + assert p2.b == i64(4) + + +main() diff --git a/integration_tests/bindpy_01.py b/integration_tests/bindpy_01.py new file mode 100644 index 0000000000..1af92c6157 --- /dev/null +++ b/integration_tests/bindpy_01.py @@ -0,0 +1,99 @@ +from lpython import i32, i64, u32, u64, f32, f64, pythoncall + +@pythoncall(module = "bindpy_01_module") +def add_ints(a: i32, b: i32, c: i32, d: i32) -> i64: + pass + +@pythoncall(module = "bindpy_01_module") +def multiply_ints(a: i32, b: i32, c: i32, d: i32) -> i64: + pass + +@pythoncall(module = "bindpy_01_module") +def add_unsigned_ints(a: u32, b: u32, c: u32, d: u32) -> u64: + pass + +@pythoncall(module = "bindpy_01_module") +def multiply_unsigned_ints(a: u32, b: u32, c: u32, d: u32) -> u64: + pass + +@pythoncall(module = "bindpy_01_module") +def add_floats(a: f32, b: f64) -> f64: + pass + +@pythoncall(module = "bindpy_01_module") +def multiply_floats(a: f32, b: f64) -> f64: + pass + +@pythoncall(module = "bindpy_01_module") +def get_hello_world(a: str, b: str) -> str: + pass + +@pythoncall(module = "bindpy_01_module") +def str_n_times(a: str, n: i32) -> str: + pass + +@pythoncall(module = "bindpy_01_module") +def get_cpython_version() -> str: + pass + +# Integers: +def test_ints(): + i: i32 + j: i32 + k: i32 + l: i32 + i = -5 + j = 24 + k = 20 + l = 92 + + assert add_ints(i, j, k, l) == i64(131) + assert multiply_ints(i, j, k, l) == i64(-220800) + +# Unsigned Integers: +def test_unsigned_ints(): + i: u32 + j: u32 + k: u32 + l: u32 + i = u32(5) + j = u32(24) + k = u32(20) + l = u32(92) + + assert add_unsigned_ints(i, j, k, l) == u64(141) + assert multiply_unsigned_ints(i, j, k, l) == u64(220800) + +# Floats +def test_floats(): + a: f32 + b: f64 + a = f32(3.14) + b = -100.00 + + assert abs(add_floats(a, b) - (-96.86)) <= 1e-4 + assert abs(multiply_floats(a, b) - (-314.0)) <= 1e-4 + +# Strings +def test_strings(): + a: str + b: str + c: str + i: i32 + a = "hello" + b = "world" + i = 3 + + assert get_hello_world(a, b) == "hello world!" + assert str_n_times(a, i) == "hellohellohello" + assert get_hello_world(str_n_times(a, i), b) == "hellohellohello world!" + +def main0(): + print("CPython version: ", get_cpython_version()) + + test_ints() + test_floats() + test_strings() + + +main0() diff --git a/integration_tests/bindpy_01_module.py b/integration_tests/bindpy_01_module.py new file mode 100644 index 0000000000..ccaa7cfa65 --- /dev/null +++ b/integration_tests/bindpy_01_module.py @@ -0,0 +1,31 @@ +def get_cpython_version(): + import platform + return platform.python_version() + +def add_ints(a, b, c, d): + e = a + b + c + d + return e + +def multiply_ints(a, b, c, d): + e = a * b * c * d + return e + +def add_unsigned_ints(a, b, c, d): + e = a + b + c + d + return e + +def multiply_unsigned_ints(a, b, c, d): + e = a * b * c * d + return e + +def add_floats(a, b): + return a + b + +def multiply_floats(a, b): + return a * b + +def get_hello_world(a, b): + return f"{a} {b}!" + +def str_n_times(a, n): + return a * n diff --git a/integration_tests/bindpy_02.py b/integration_tests/bindpy_02.py new file mode 100644 index 0000000000..9328029200 --- /dev/null +++ b/integration_tests/bindpy_02.py @@ -0,0 +1,80 @@ +from lpython import i32, f64, pythoncall, Const +from numpy import empty, int32, float64 + +@pythoncall(module = "bindpy_02_module") +def get_cpython_version() -> str: + pass + +@pythoncall(module = "bindpy_02_module") +def get_int_array_sum(a: i32[:]) -> i32: + pass + +@pythoncall(module = "bindpy_02_module") +def get_int_array_product(a: i32[:]) -> i32: + pass + +@pythoncall(module = "bindpy_02_module") +def get_float_array_sum(a: f64[:]) -> f64: + pass + +@pythoncall(module = "bindpy_02_module") +def get_float_array_product(a: f64[:]) -> f64: + pass + +@pythoncall(module = "bindpy_02_module") +def show_array_dot_product(a: i32[:], b: f64[:]): + pass + +# Integers: +def test_array_ints(): + n: Const[i32] = 5 + a: i32[n] = empty([n], dtype=int32) + + i: i32 + for i in range(n): + a[i] = i + 10 + + assert get_int_array_sum(a) == i32(60) + assert get_int_array_product(a) == i32(240240) + +# Floats +def test_array_floats(): + n: Const[i32] = 3 + m: Const[i32] = 5 + b: f64[n, m] = empty([n, m], dtype=float64) + + i: i32 + j: i32 + + for i in range(n): + for j in range(m): + b[i, j] = f64((i + 1) * (j + 1)) + + assert abs(get_float_array_sum(b) - (90.000000)) <= 1e-4 + assert abs(get_float_array_product(b) - (13436928000.000000)) <= 1e-4 + +def test_array_broadcast(): + n: Const[i32] = 3 + m: Const[i32] = 5 + a: i32[n] = empty([n], dtype=int32) + b: f64[n, m] = empty([n, m], dtype=float64) + + i: i32 + j: i32 + for i in range(n): + a[i] = i + 10 + + for i in range(n): + for j in range(m): + b[i, j] = f64((i + 1) * (j + 1)) + + show_array_dot_product(a, b) + +def main0(): + print("CPython version: ", get_cpython_version()) + + test_array_ints() + test_array_floats() + test_array_broadcast() + +main0() diff --git a/integration_tests/bindpy_02_module.py b/integration_tests/bindpy_02_module.py new file mode 100644 index 0000000000..5e76238a8e --- /dev/null +++ b/integration_tests/bindpy_02_module.py @@ -0,0 +1,21 @@ +import numpy as np + +def get_cpython_version(): + import platform + return platform.python_version() + +def get_int_array_sum(a): + return np.sum(a) + +def get_int_array_product(a): + return np.prod(a) + +def get_float_array_sum(a): + return np.sum(a) + +def get_float_array_product(a): + return np.prod(a) + +def show_array_dot_product(a, b): + print(a, b) + print(a @ b) diff --git a/integration_tests/bindpy_03.py b/integration_tests/bindpy_03.py new file mode 100644 index 0000000000..30583afcc4 --- /dev/null +++ b/integration_tests/bindpy_03.py @@ -0,0 +1,136 @@ +from lpython import i32, i64, f64, pythoncall, Const, TypeVar +from numpy import empty, int32, int64, float64 + +n = TypeVar("n") +m = TypeVar("m") +p = TypeVar("p") +q = TypeVar("q") +r = TypeVar("r") + +@pythoncall(module = "bindpy_03_module") +def get_cpython_version() -> str: + pass + +@pythoncall(module = "bindpy_03_module") +def get_int_array_sum(n: i32, a: i32[:], b: i32[:]) -> i32[n]: + pass + +@pythoncall(module = "bindpy_03_module") +def get_int_array_product(n: i32, a: i32[:], b: i32[:]) -> i32[n]: + pass + +@pythoncall(module = "bindpy_03_module") +def get_float_array_sum(n: i32, m: i32, a: f64[:], b: f64[:]) -> f64[n, m]: + pass + +@pythoncall(module = "bindpy_03_module") +def get_float_array_product(n: i32, m: i32, a: f64[:], b: f64[:]) -> f64[n, m]: + pass + +@pythoncall(module = "bindpy_03_module") +def get_array_dot_product(m: i32, a: i64[:], b: f64[:]) -> f64[m]: + pass + +@pythoncall(module = "bindpy_03_module") +def get_multidim_array_i64(p: i32, q: i32, r: i32) -> i64[p, q, r]: + pass + +# Integers: +def test_array_ints(): + n: Const[i32] = 5 + a: i32[n] = empty([n], dtype=int32) + b: i32[n] = empty([n], dtype=int32) + + i: i32 + for i in range(n): + a[i] = i + 10 + for i in range(n): + b[i] = i + 20 + + c: i32[n] = get_int_array_sum(n, a, b) + print(c) + for i in range(n): + assert c[i] == (i + i + 30) + + + c = get_int_array_product(n, a, b) + print(c) + for i in range(n): + assert c[i] == ((i + 10) * (i + 20)) + +# Floats +def test_array_floats(): + n: Const[i32] = 3 + m: Const[i32] = 5 + a: f64[n, m] = empty([n, m], dtype=float64) + b: f64[n, m] = empty([n, m], dtype=float64) + + i: i32 + j: i32 + + for i in range(n): + for j in range(m): + a[i, j] = f64((i + 10) * (j + 10)) + + for i in range(n): + for j in range(m): + b[i, j] = f64((i + 20) * (j + 20)) + + c: f64[n, m] = get_float_array_sum(n, m, a, b) + print(c) + for i in range(n): + for j in range(m): + assert abs(c[i, j] - (f64((i + 10) * (j + 10)) + f64((i + 20) * (j + 20)))) <= 1e-4 + + c = get_float_array_product(n, m, a, b) + print(c) + for i in range(n): + for j in range(m): + assert abs(c[i, j] - (f64((i + 10) * (j + 10)) * f64((i + 20) * (j + 20)))) <= 1e-4 + +def test_array_broadcast(): + n: Const[i32] = 3 + m: Const[i32] = 5 + a: i64[n] = empty([n], dtype=int64) + b: f64[n, m] = empty([n, m], dtype=float64) + + i: i32 + j: i32 + for i in range(n): + a[i] = i64(i + 10) + + for i in range(n): + for j in range(m): + b[i, j] = f64((i + 1) * (j + 1)) + + c: f64[m] = get_array_dot_product(m, a, b) + print(c) + assert abs(c[0] - (68.0)) <= 1e-4 + assert abs(c[1] - (136.0)) <= 1e-4 + assert abs(c[2] - (204.0)) <= 1e-4 + assert abs(c[3] - (272.0)) <= 1e-4 + assert abs(c[4] - (340.0)) <= 1e-4 + +def test_multidim_array_return_i64(): + p: Const[i32] = 3 + q: Const[i32] = 4 + r: Const[i32] = 5 + a: i64[p, q, r] = empty([p, q, r], dtype=int64) + a = get_multidim_array_i64(p, q, r) + print(a) + + i: i32; j: i32; k: i32 + for i in range(p): + for j in range(q): + for k in range(r): + assert a[i, j, k] == i64(i * 2 + j * 3 + k * 4) + +def main0(): + print("CPython version: ", get_cpython_version()) + + test_array_ints() + test_array_floats() + test_array_broadcast() + test_multidim_array_return_i64() + +main0() diff --git a/integration_tests/bindpy_03_module.py b/integration_tests/bindpy_03_module.py new file mode 100644 index 0000000000..0c702067c4 --- /dev/null +++ b/integration_tests/bindpy_03_module.py @@ -0,0 +1,31 @@ +import numpy as np + +def get_cpython_version(): + import platform + return platform.python_version() + +def get_int_array_sum(n, a, b): + return np.add(a, b) + +def get_int_array_product(n, a, b): + return np.multiply(a, b) + +def get_float_array_sum(n, m, a, b): + return np.add(a, b) + +def get_float_array_product(n, m, a, b): + return np.multiply(a, b) + +def get_array_dot_product(m, a, b): + print(a, b) + c = a @ b + print(c) + return c + +def get_multidim_array_i64(p, q, r): + a = np.empty([p, q, r], dtype = np.int64) + for i in range(p): + for j in range(q): + for k in range(r): + a[i, j, k] = i * 2 + j * 3 + k * 4 + return a diff --git a/integration_tests/bindpy_04.py b/integration_tests/bindpy_04.py new file mode 100644 index 0000000000..0c38baa6f2 --- /dev/null +++ b/integration_tests/bindpy_04.py @@ -0,0 +1,150 @@ +from lpython import i1, i32, u32, f64, c64, pythoncall, Const, TypeVar +from numpy import empty, uint32, complex128 + +n = TypeVar("n") +m = TypeVar("m") + +# Defining the pythoncall decorator functions +@pythoncall(module = "bindpy_04_module") +def get_uint_array_sum(n: i32, a: u32[:], b: u32[:]) -> u32[n]: + pass + +@pythoncall(module = "bindpy_04_module") +def get_bool_array_or(n: i32, a: i1[:], b: i1[:]) -> i1[n]: + pass + +@pythoncall(module = "bindpy_04_module") +def get_complex_array_product(n: i32, a: c64[:], b: c64[:]) -> c64[n]: + pass + +@pythoncall(module = "bindpy_04_module") +def get_2D_uint_array_sum(n: i32, m: i32, a: u32[:,:], b: u32[:,:]) -> u32[n,m]: + pass + +@pythoncall(module = "bindpy_04_module") +def get_2D_bool_array_and(n: i32, m: i32, a: i1[:,:], b: i1[:,:]) -> i1[n,m]: + pass + +@pythoncall(module = "bindpy_04_module") +def get_2D_complex_array_sum(n: i32, m: i32, a: c64[:,:], b: c64[:,:]) -> c64[n,m]: + pass + +# Unsigned Integers +def test_array_uints(): + n: Const[i32] = 5 + a: u32[n] = empty([n], dtype=uint32) + b: u32[n] = empty([n], dtype=uint32) + + i: i32 + for i in range(n): + a[i] = u32(i + 10) + b[i] = u32(i + 20) + + c: u32[n] = get_uint_array_sum(n, a, b) + print(c) + for i in range(n): + assert c[i] == u32(i * 2 + 30) + +def test_2D_array_uints(): + n: Const[i32] = 3 + m: Const[i32] = 4 + a: u32[n, m] = empty([n, m], dtype=uint32) + b: u32[n, m] = empty([n, m], dtype=uint32) + + i: i32 + j: i32 + for i in range(n): + for j in range(m): + a[i, j] = u32(i * 10 + j) + b[i, j] = u32(i * 20 + j) + + c: u32[n, m] = get_2D_uint_array_sum(n, m, a, b) + print(c) + for i in range(n): + for j in range(m): + assert c[i, j] == u32(i * 30 + 2*j) + +# Boolean +def test_array_bools(): + n: Const[i32] = 5 + a: i1[n] = empty([n], dtype=bool) + b: i1[n] = empty([n], dtype=bool) + + i: i32 + for i in range(n): + a[i] = bool(i % 2 == 0) + b[i] = bool(i % 3 == 0) + + c: i1[n] = get_bool_array_or(n, a, b) + print(c) + for i in range(n): + assert c[i] == bool((i % 2 == 0) or (i % 3 == 0)) + +def test_2D_array_bools(): + n: Const[i32] = 3 + m: Const[i32] = 4 + a: i1[n, m] = empty([n, m], dtype=bool) + b: i1[n, m] = empty([n, m], dtype=bool) + + i: i32 + j: i32 + for i in range(n): + for j in range(m): + a[i, j] = bool(i % 2 == 0) + b[i, j] = bool(j % 2 == 0) + + c: i1[n, m] = get_2D_bool_array_and(n, m, a, b) + print(c) + for i in range(n): + for j in range(m): + assert c[i, j] == bool((i % 2 == 0) and (j % 2 == 0)) + +# Complex +def test_array_complexes(): + n: Const[i32] = 5 + a: c64[n] = empty([n], dtype=complex128) + b: c64[n] = empty([n], dtype=complex128) + + i: i32 + for i in range(n): + a[i] = c64(complex(i, i + 10)) + b[i] = c64(complex(i + 1, i + 11)) + + c: c64[n] = get_complex_array_product(n, a, b) + print(c) + for i in range(n): + p: f64 = f64(i) + q: f64 = f64(i + 10) + r: f64 = f64(i + 1) + s: f64 = f64(i + 11) + assert abs(c[i] - c64(complex((p*r - q*s), (p*s + q*r)))) <= 1e-5 + +def test_2D_array_complexes(): + n: Const[i32] = 3 + m: Const[i32] = 4 + a: c64[n, m] = empty([n, m], dtype=complex128) + b: c64[n, m] = empty([n, m], dtype=complex128) + + i: i32 + j: i32 + for i in range(n): + for j in range(m): + a[i, j] = c64(complex(i, 10*j)) + b[i, j] = c64(complex(i + 1, 10 * (j + 1))) + + c: c64[n, m] = get_2D_complex_array_sum(n, m, a, b) + print(c) + for i in range(n): + for j in range(m): + assert abs(c[i, j] - c64(complex(2*i + 1, 20*j + 10))) <= 1e-5 + +def main0(): + test_array_uints() + test_array_bools() + test_array_complexes() + + test_2D_array_uints() + test_2D_array_bools() + test_2D_array_complexes() + +main0() diff --git a/integration_tests/bindpy_04_module.py b/integration_tests/bindpy_04_module.py new file mode 100644 index 0000000000..f856a84074 --- /dev/null +++ b/integration_tests/bindpy_04_module.py @@ -0,0 +1,21 @@ +import numpy as np + +def get_uint_array_sum(n, a, b): + return np.add(a, b) + +def get_bool_array_or(n, a, b): + return np.logical_or(a, b) + +def get_complex_array_product(n, a, b): + print(a, b) + print(np.multiply(a, b)) + return np.multiply(a, b) + +def get_2D_uint_array_sum(n, m, a, b): + return np.add(a, b) + +def get_2D_bool_array_and(n, m, a, b): + return np.logical_and(a, b) + +def get_2D_complex_array_sum(n, m, a, b): + return np.add(a, b) diff --git a/integration_tests/bindpy_05.py b/integration_tests/bindpy_05.py new file mode 100644 index 0000000000..8cb4422cd0 --- /dev/null +++ b/integration_tests/bindpy_05.py @@ -0,0 +1,79 @@ +from lpython import ccall, Pointer, i32, i64, empty_c_void_p, CPtr, pointer + +@ccall(header="Python.h") +def Py_Initialize(): + pass + +@ccall(header="Python.h") +def Py_DecodeLocale(s: str, p: CPtr) -> CPtr: + pass + +@ccall(header="Python.h") +def PySys_SetArgv(n: i32, args: Pointer[CPtr]): + pass + +@ccall(header="Python.h") +def Py_FinalizeEx() -> i32: + pass + +@ccall(header="Python.h") +def PyUnicode_FromString(s: str) -> CPtr: + pass + +@ccall(header="Python.h") +def PyImport_Import(name: CPtr) -> CPtr: + pass + +@ccall(header="Python.h") +def _Py_DecRef(name: CPtr): + pass + +@ccall(header="Python.h") +def PyObject_GetAttrString(m: CPtr, s: str) -> CPtr: + pass + +@ccall(header="Python.h") +def PyTuple_New(n: i32) -> CPtr: + pass + +@ccall(header="Python.h") +def PyObject_CallObject(a: CPtr, b: CPtr) -> CPtr: + pass + +@ccall(header="Python.h") +def PyLong_AsLongLong(a: CPtr) -> i64: + pass + +def my_f(): + pName: CPtr; pModule: CPtr; pFunc: CPtr; pArgs: CPtr; pValue: CPtr + + pName = PyUnicode_FromString("bindpy_05_module") + assert bool(pName), "Failed to convert to unicode string bindpy_05_module\n" + + pModule = PyImport_Import(pName) + _Py_DecRef(pName) + assert bool(pModule), "Failed to load python module bindpy_05_module\n" + + pFunc = PyObject_GetAttrString(pModule, "my_f") + assert bool(pFunc), "Cannot find function my_f\n" + + pArgs = PyTuple_New(0) + pValue = PyObject_CallObject(pFunc, pArgs) + _Py_DecRef(pArgs) + assert bool(pValue), "Call to my_f failed\n" + + ans: i64 = PyLong_AsLongLong(pValue) + print("Ans is", ans) + assert ans == i64(5) + + +def main0(): + Py_Initialize() + argv1: CPtr = Py_DecodeLocale("", empty_c_void_p()) + PySys_SetArgv(1, pointer(argv1, i64)) + + my_f() + + assert(Py_FinalizeEx() >= 0), "BindPython: Unknown Error in FinalizeEx()\n" + +main0() diff --git a/integration_tests/bindpy_05_module.py b/integration_tests/bindpy_05_module.py new file mode 100644 index 0000000000..ce873c0044 --- /dev/null +++ b/integration_tests/bindpy_05_module.py @@ -0,0 +1,3 @@ +def my_f(): + print("hello from python") + return 5 diff --git a/integration_tests/bindpy_06.py b/integration_tests/bindpy_06.py new file mode 100644 index 0000000000..9b077d2e46 --- /dev/null +++ b/integration_tests/bindpy_06.py @@ -0,0 +1,72 @@ +from lpython import i32, f64, pythoncall, Const +from numpy import empty, int32, float64 + + +@pythoncall(module = "bindpy_06_module") +def get_cpython_version() -> str: + pass + + +@pythoncall(module = "bindpy_06_module") +def get_modified_dict(d: dict[str, i32]) -> dict[str, i32]: + pass + + +@pythoncall(module = "bindpy_06_module") +def get_modified_list(d: list[str]) -> list[str]: + pass + +@pythoncall(module = "bindpy_06_module") +def get_modified_tuple(t: tuple[i32, i32]) -> tuple[i32, i32, i32]: + pass + + +@pythoncall(module = "bindpy_06_module") +def get_modified_set(s: set[i32]) -> set[i32]: + pass + + +def test_list(): + l: list[str] = ["LPython"] + lr: list[str] = get_modified_list(l) + assert len(lr) == 2 + assert lr[0] == "LPython" + assert lr[1] == "LFortran" + + +def test_tuple(): + t: tuple[i32, i32] = (2, 4) + tr: tuple[i32, i32, i32] = get_modified_tuple(t) + assert tr[0] == t[0] + assert tr[1] == t[1] + assert tr[2] == t[0] + t[1] + + +def test_set(): + s: set[i32] = {1, 2, 3} + sr: set[i32] = get_modified_set(s) + assert len(sr) == 4 + assert 1 in sr + assert 2 in sr + assert 3 in sr + assert 100 in sr + + +def test_dict(): + d: dict[str, i32] = { + "LPython": 50 + } + dr: dict[str, i32] = get_modified_dict(d) + assert len(dr) == 2 + assert dr["LPython"] == 50 + assert dr["LFortran"] == 100 + + +def main0(): + test_list() + test_tuple() + test_set() + test_dict() + + +main0() diff --git a/integration_tests/bindpy_06_module.py b/integration_tests/bindpy_06_module.py new file mode 100644 index 0000000000..a22386e1b7 --- /dev/null +++ b/integration_tests/bindpy_06_module.py @@ -0,0 +1,24 @@ +import platform + + +def get_cpython_version(): + return platform.python_version() + + +def get_modified_dict(d): + d["LFortran"] = 100 + return d + + +def get_modified_list(l): + l.append("LFortran") + return l + + +def get_modified_tuple(t): + return (t[0], t[1], t[0] + t[1]) + + +def get_modified_set(s): + s.add(100) + return s diff --git a/integration_tests/bit_operations_i32.py b/integration_tests/bit_operations_i32.py index 67934c8ce3..7d01f1d279 100644 --- a/integration_tests/bit_operations_i32.py +++ b/integration_tests/bit_operations_i32.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_bitnot(): x: i32 = 5 diff --git a/integration_tests/bit_operations_i64.py b/integration_tests/bit_operations_i64.py index c1ac77c413..efc61f6d33 100644 --- a/integration_tests/bit_operations_i64.py +++ b/integration_tests/bit_operations_i64.py @@ -1,4 +1,4 @@ -from ltypes import i64 +from lpython import i64 def test_bitnot(): x: i64 = i64(123) diff --git a/integration_tests/c_mangling.py b/integration_tests/c_mangling.py new file mode 100644 index 0000000000..5acc099f41 --- /dev/null +++ b/integration_tests/c_mangling.py @@ -0,0 +1,23 @@ +def f(): + int : str + int = "abc" + print(int) + + char : str + char = "char_variable" + print(char) + + void : str + void = "void_variable" + print(void) + + auto : str + auto = "auto_variable" + print(auto) + + + case : str + case = "case_variable" + print(case) + +f() diff --git a/integration_tests/callback_01.py b/integration_tests/callback_01.py new file mode 100644 index 0000000000..e297c98630 --- /dev/null +++ b/integration_tests/callback_01.py @@ -0,0 +1,26 @@ +from lpython import i32, Callable + + +def f(x: i32) -> i32: + return x + 1 + +def f2(x: i32) -> i32: + return x + 10 + +def f3(x: i32) -> i32: + return f(x) + f2(x) + + +def g(func: Callable[[i32], i32], arg: i32) -> i32: + ret: i32 + ret = func(arg) + return ret + + +def check(): + assert g(f, 10) == 11 + assert g(f2, 20) == 30 + assert g(f3, 5) == 21 + + +check() diff --git a/integration_tests/callback_02.py b/integration_tests/callback_02.py new file mode 100644 index 0000000000..330f75cbbf --- /dev/null +++ b/integration_tests/callback_02.py @@ -0,0 +1,18 @@ +from lpython import ccallback, i32, Callable + +# test issue 2169 + +def foo(x : i32) -> i32: + return x**2 + +def bar(func : Callable[[i32], i32], arg : i32) -> i32: + return func(arg) + +@ccallback +def entry_point() -> None: + z: i32 = 5 + x: i32 = bar(foo, z) + assert z**2 == x + + +entry_point() diff --git a/integration_tests/callback_03.py b/integration_tests/callback_03.py new file mode 100644 index 0000000000..0f1f62e722 --- /dev/null +++ b/integration_tests/callback_03.py @@ -0,0 +1,13 @@ +from lpython import i32, Callable + +def foo(x : i32) -> None: + print(x) + assert x == 3 + +def bar(func : Callable[[i32], None], arg : i32) -> i32: + func(arg) + +def main0(): + bar(foo, 3) + +main0() diff --git a/integration_tests/callback_04.py b/integration_tests/callback_04.py new file mode 100644 index 0000000000..8268574f28 --- /dev/null +++ b/integration_tests/callback_04.py @@ -0,0 +1,18 @@ +import lpython +from lpython import i32 +from types import FunctionType +import callback_04_module + +lpython.CTypes.emulations = {k: v for k, v in callback_04_module.__dict__.items() + if isinstance(v, FunctionType)} + + +def foo(x : i32) -> i32: + assert x == 3 + print(x) + return x + +def entry_point() -> None: + callback_04_module.bar(foo, 3) + +entry_point() diff --git a/integration_tests/callback_04_module.py b/integration_tests/callback_04_module.py new file mode 100644 index 0000000000..13cfef375e --- /dev/null +++ b/integration_tests/callback_04_module.py @@ -0,0 +1,4 @@ +from lpython import i32, Callable + +def bar(func : Callable[[i32], i32], arg : i32) -> i32: + return func(arg) diff --git a/integration_tests/cast_01.py b/integration_tests/cast_01.py new file mode 100644 index 0000000000..ee2b5b01df --- /dev/null +++ b/integration_tests/cast_01.py @@ -0,0 +1,18 @@ +from lpython import i32, u8, u32, dataclass, field +from numpy import empty, uint8 + +@dataclass +class LPBHV_small: + dim : i32 = 4 + a : u8[4] = field(default_factory=lambda: empty(4, dtype=uint8)) + +def main0(): + lphv_small : LPBHV_small = LPBHV_small() + i: i32 + for i in range(4): + lphv_small.a[i] = u8(10 + i) + elt: u32 = u32(lphv_small.a[i]) + print(elt) + assert elt == u32(10 + i) + +main0() diff --git a/integration_tests/cast_02.py b/integration_tests/cast_02.py new file mode 100644 index 0000000000..f984e5730c --- /dev/null +++ b/integration_tests/cast_02.py @@ -0,0 +1,41 @@ +from lpython import u8, u16, u32, u64 + +def test_01(): + x : u32 = u32(10) + print(x) + assert x == u32(10) + + y: u16 = u16(x) + print(y) + assert y == u16(10) + + z: u64 = u64(y) + print(z) + assert z == u64(10) + + w: u8 = u8(z) + print(w) + assert w == u8(10) + +def test_02(): + x : u64 = u64(11) + print(x) + assert x == u64(11) + + y: u8 = u8(x) + print(y) + assert y == u8(11) + + z: u16 = u16(y) + print(z) + assert z == u16(11) + + w: u32 = u32(z) + print(w) + assert w == u32(11) + +def main0(): + test_01() + test_02() + +main0() diff --git a/integration_tests/class_01.py b/integration_tests/class_01.py new file mode 100644 index 0000000000..103cb612c3 --- /dev/null +++ b/integration_tests/class_01.py @@ -0,0 +1,28 @@ +from lpython import i32,f64 +from math import sqrt + +class coord: + def __init__(self: "coord"): + self.x: i32 = 3 + self.y: i32 = 4 + +def main(): + p1: coord = coord() + sq_dist : i32 = p1.x*p1.x + p1.y*p1.y + dist : f64 = sqrt(f64(sq_dist)) + print("Squared Distance from origin = ", sq_dist) + assert sq_dist == 25 + print("Distance from origin = ", dist) + assert dist == f64(5) + print("p1.x = 6") + print("p1.y = 8") + p1.x = i32(6) + p1.y = 8 + sq_dist = p1.x*p1.x + p1.y*p1.y + dist = sqrt(f64(sq_dist)) + print("Squared Distance from origin = ", sq_dist) + assert sq_dist == 100 + print("Distance from origin = ", dist) + assert dist == f64(10) + +main() diff --git a/integration_tests/class_02.py b/integration_tests/class_02.py new file mode 100644 index 0000000000..94d92a9ec6 --- /dev/null +++ b/integration_tests/class_02.py @@ -0,0 +1,43 @@ +from lpython import i32 +class Character: + def __init__(self:"Character", name:str, health:i32, attack_power:i32): + self.name :str = name + self.health :i32 = health + self.attack_power : i32 = attack_power + self.is_immortal : bool = False + + def attack(self:"Character", other:"Character")->str: + other.health -= self.attack_power + return self.name+" attacks "+ other.name+" for "+str(self.attack_power)+" damage." + + def is_alive(self:"Character")->bool: + if self.is_immortal: + return True + else: + return self.health > 0 + +def main(): + hero : Character = Character("Hero", 10, 20) + monster : Character = Character("Monster", 50, 15) + print(hero.attack(monster)) + print(monster.health) + assert monster.health == 30 + print(monster.is_alive()) + assert monster.is_alive() == True + print("Hero gains temporary immortality") + hero.is_immortal = True + print(monster.attack(hero)) + print(hero.health) + assert hero. health == -5 + print(hero.is_alive()) + assert hero.is_alive() == True + print("Hero's immortality runs out") + hero.is_immortal = False + print(hero.is_alive()) + assert hero.is_alive() == False + print("Restarting") + hero = Character("Hero", 10, 20) + print(hero.is_alive()) + assert hero.is_alive() == True + +main() diff --git a/integration_tests/class_03.py b/integration_tests/class_03.py new file mode 100644 index 0000000000..8e4d9eded6 --- /dev/null +++ b/integration_tests/class_03.py @@ -0,0 +1,24 @@ +from lpython import f64 +from math import pi + +class Circle: + def __init__(self:"Circle", radius:f64): + self.radius :f64 = radius + + def circle_area(self:"Circle")->f64: + return pi * self.radius ** 2.0 + + def circle_print(self:"Circle"): + area : f64 = self.circle_area() + print("Circle: r = ",str(self.radius)," area = ",str(area)) + +def main(): + c : Circle = Circle(1.0) + c.circle_print() + assert abs(c.circle_area() - 3.141593) <= 1e-6 + c.radius = 1.5 + c.circle_print() + assert abs(c.circle_area() - 7.068583) < 1e-6 + +if __name__ == "__main__": + main() diff --git a/integration_tests/class_04.py b/integration_tests/class_04.py new file mode 100644 index 0000000000..7798526331 --- /dev/null +++ b/integration_tests/class_04.py @@ -0,0 +1,46 @@ +from lpython import i32 +class Person: + def __init__(self:"Person", first:str, last:str, birthyear:i32, sgender:str): + self.first:str = first + self.last:str = last + self.birthyear:i32 = birthyear + self.sgender:str = sgender + + def describe(self:"Person"): + print("first: " + self.first) + print("last: " + self.last) + print("birthyear: " + str(self.birthyear)) + print("sgender: " + self.sgender) + +class Employee: + def __init__(self:"Employee", person:Person, hire_date:i32, department:str): + self.person:Person = person + self.hire_date:i32 = hire_date + self.department:str = department + + def describe(self:"Employee"): + self.person.describe() + print("hire_date: " + str(self.hire_date)) + print("department: " + self.department) + +def main(): + jack:Person = Person("Jack", "Smith", 1984, "M") + jill_p:Person = Person("Jill", "Smith", 1984, "F") + jill:Employee = Employee(jill_p, 2003, "sales") + + jack.describe() + assert jack.first == "Jack" + assert jack.last == "Smith" + assert jack.birthyear == 1984 + assert jack.sgender == "M" + + jill.describe() + assert jill.person.first == "Jill" + assert jill.person.last == "Smith" + assert jill.person.birthyear == 1984 + assert jill.person.sgender == "F" + assert jill.department == "sales" + assert jill.hire_date == 2003 + +if __name__ == '__main__': + main() diff --git a/integration_tests/class_05.py b/integration_tests/class_05.py new file mode 100644 index 0000000000..75af54cd8f --- /dev/null +++ b/integration_tests/class_05.py @@ -0,0 +1,37 @@ +from lpython import i32 + +class Animal: + def __init__(self:"Animal"): + self.species: str = "Generic Animal" + self.age: i32 = 0 + self.is_domestic: bool = True + +class Dog(Animal): + def __init__(self:"Dog", name:str, age:i32): + super().__init__() + self.species: str = "Dog" + self.name: str = name + self.age: i32 = age + +class Cat(Animal): + def __init__(self:"Cat", name: str, age: i32): + super().__init__() + self.species: str = "Cat" + self.name:str = name + self.age: i32 = age + +def main(): + dog: Dog = Dog("Buddy", 5) + cat: Cat = Cat("Whiskers", 3) + op1: str = str(dog.name+" is a "+str(dog.age)+"-year-old "+dog.species+".") + print(op1) + assert op1 == "Buddy is a 5-year-old Dog." + print(dog.is_domestic) + assert dog.is_domestic == True + op2: str = str(cat.name+ " is a "+ str(cat.age)+ "-year-old "+ cat.species+ ".") + print(op2) + assert op2 == "Whiskers is a 3-year-old Cat." + print(cat.is_domestic) + assert cat.is_domestic == True + +main() diff --git a/integration_tests/class_06.py b/integration_tests/class_06.py new file mode 100644 index 0000000000..868985efdf --- /dev/null +++ b/integration_tests/class_06.py @@ -0,0 +1,36 @@ +from lpython import i32 + +class Base(): + def __init__(self:"Base"): + self.x : i32 = 10 + + def get_x(self:"Base")->i32: + print(self.x) + return self.x + +#Testing polymorphic fn calls +def get_x_static(d: Base)->i32: + print(d.x) + return d.x + +class Derived(Base): + def __init__(self: "Derived"): + super().__init__() + self.y : i32 = 20 + + def get_y(self:"Derived")->i32: + print(self.y) + return self.y + + +def main(): + d : Derived = Derived() + x : i32 = get_x_static(d) + assert x == 10 + # Testing parent method call using der obj + x = d.get_x() + assert x == 10 + y: i32 = d.get_y() + assert y == 20 + +main() diff --git a/integration_tests/comp_01.py b/integration_tests/comp_01.py index b04eb9a1d0..41ac380a5a 100644 --- a/integration_tests/comp_01.py +++ b/integration_tests/comp_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def compI32(x: i32, y: i32): print(x) diff --git a/integration_tests/const_01.py b/integration_tests/const_01.py index 2db1a91b0f..377f3ab676 100644 --- a/integration_tests/const_01.py +++ b/integration_tests/const_01.py @@ -1,4 +1,4 @@ -from ltypes import Const, i32, i64, f32, f64 +from lpython import Const, i32, i64, f32, f64 def test_const_variables(): xci: Const[i32] = i32(0.0) @@ -13,6 +13,11 @@ def test_const_variables(): ycf: Const[f64] = 3.0 yf: f64 = 3.0 + print(xci, xi) + print(yci, yi) + print(xcf, xf) + print(ycf, yf) + assert xci == xi assert yci == yi assert xcf == xf diff --git a/integration_tests/const_02.py b/integration_tests/const_02.py index c84fea5a9d..b8c69b743c 100644 --- a/integration_tests/const_02.py +++ b/integration_tests/const_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, Const +from lpython import i32, f64, Const def f(x: Const[i32]) -> i32: return x + 1 diff --git a/integration_tests/const_03.py b/integration_tests/const_03.py index 40ebf818d5..13d448c0a3 100644 --- a/integration_tests/const_03.py +++ b/integration_tests/const_03.py @@ -1,4 +1,4 @@ -from ltypes import i64, f64, i32, Const, ccall +from lpython import i64, f64, i32, Const, ccall CONST_1: Const[f64] = 32.0 CONST_2: Const[f64] = CONST_1 * 2.0 diff --git a/integration_tests/const_04.py b/integration_tests/const_04.py index 6acd01dbd0..e65b5292fd 100644 --- a/integration_tests/const_04.py +++ b/integration_tests/const_04.py @@ -1,4 +1,4 @@ -from ltypes import i32, i16, Const +from lpython import i32, i16, Const from numpy import empty, int16 def sum_const_array(array: Const[i16[:]], size: i32) -> i16: diff --git a/integration_tests/def_func_01.py b/integration_tests/def_func_01.py new file mode 100644 index 0000000000..2564cff13e --- /dev/null +++ b/integration_tests/def_func_01.py @@ -0,0 +1,76 @@ +from lpython import i32,i64 + +def factorial_1(x: i32, y:i32 =1) ->i32 : + if x <= 1: + return y + return x * factorial_1(x-1) + +def factorial_2(x: i32, y:i32=3 ,z:i32 =2) ->i32: + if x ==4: + return x * y * z + return x * factorial_2(x-1) + +def default_func(x : str ="Hello", y : str = " ", z : str = "World") ->str: + return x + y + z + + +def even_positions(iterator : i32, to_add : str = "?")-> str: + if (iterator == 10): return "" + if iterator%2 == 0 : + return to_add + even_positions(iterator+1,"X") + return to_add +even_positions(iterator+1) + + + +def test_factorial_1(): + test_00 : i32 = factorial_1(1) + print("test_00 is =>", test_00) + assert test_00 == 1 + + test_01 : i32 = factorial_1(5,0) + print("test_01 is =>", test_01) + assert test_01 == 120 + + test_02 : i32 = factorial_1(1,5555) + print("test_02 is =>", test_02) + assert test_02 == 5555 + +def test_factorial_2(): + test_03 : i32 =factorial_2(5,99999,99999) + print("test_03 is =>", test_03) + assert test_03 == 120 + + test_04 : i32 = factorial_2(4,-1,100) + print("test_04 is =>", test_04) + assert test_04 == -400 + +def test_default_func(): + test_05 :str = default_func() + print("test_05 is =>", test_05) + assert test_05 == "Hello World" + + test_06 :str = default_func(y = "|||",x="Hi") + print("test_06 is =>", test_06) + assert test_06 == "Hi|||World" + + test_07 :str = default_func(y = "++",z = "LPython") + print("test_07 is =>", test_07) + assert test_07 == "Hello++LPython" + + test_8 :str = default_func("Welcome",z = "LPython") + print("test_8 is =>", test_8) + assert test_8 == "Welcome LPython" + +def test_even_positions(): + test_09 : str = even_positions(0) + print("test_09 is =>", test_09) + assert test_09 == "?X?X?X?X?X" + + test_10 : str = even_positions(0,"W") + print("test_10 is =>", test_10) + assert test_10 == "WX?X?X?X?X" + +test_factorial_1() +test_factorial_2() +test_default_func() +test_even_positions() diff --git a/integration_tests/elemental_01.py b/integration_tests/elemental_01.py index 22b44b90ed..0a2787c7ed 100644 --- a/integration_tests/elemental_01.py +++ b/integration_tests/elemental_01.py @@ -1,5 +1,5 @@ -from ltypes import i32, f64, f32 -from numpy import empty, sin, cos, reshape +from lpython import i32, f64, f32 +from numpy import empty, sin, cos, reshape, int32, float32, float64 def verify1d(array: f32[:], result: f32[:], size: i32): i: i32 @@ -35,7 +35,7 @@ def verify2d(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32): def verify1d_sum(array_a: f64[:], array_b: f64[:], result: f64[:], size: i32): i: i32 eps: f64 - eps = 1e-12 + eps = 1e-9 for i in range(size): assert abs(array_a[i]**2.0 + 5.0*array_b[i]**3.0 - result[i]) <= eps @@ -44,7 +44,7 @@ def verify1d_sum(array_a: f64[:], array_b: f64[:], result: f64[:], size: i32): def verify1d_mul(array_a: f64[:], array_b: f64[:], result: f64[:], size: i32): i: i32 eps: f64 - eps = 1e-12 + eps = 1e-5 for i in range(size): assert abs(array_a[i]**2.0 * 5.0*array_b[i]**3.0 - result[i]) <= eps @@ -55,9 +55,9 @@ def elemental_sum(): j: i32 k: i32 - array_a: f64[100] = empty(100) - array_b: f64[100] = empty(100) - array_c: f64[100] = empty(100) + array_a: f64[100] = empty(100, dtype=float64) + array_b: f64[100] = empty(100, dtype=float64) + array_c: f64[100] = empty(100, dtype=float64) for i in range(100): array_a[i] = float(i) @@ -74,9 +74,9 @@ def elemental_mul(): j: i32 k: i32 - array_a: f64[100] = empty(100) - array_b: f64[100] = empty(100) - array_c: f64[100] = empty(100) + array_a: f64[100] = empty(100, dtype=float64) + array_b: f64[100] = empty(100, dtype=float64) + array_c: f64[100] = empty(100, dtype=float64) for i in range(100): array_a[i] = float(i) @@ -93,8 +93,8 @@ def elemental_sin(): j: i32 k: i32 - array1d: f32[256] = empty(256) - sin1d: f32[256] = empty(256) + array1d: f32[256] = empty(256, dtype=float32) + sin1d: f32[256] = empty(256, dtype=float32) for i in range(256): array1d[i] = f32(i) @@ -103,24 +103,24 @@ def elemental_sin(): verify1d(array1d, sin1d, 256) - arraynd: f64[256, 64, 16] = empty((256, 64, 16)) - sinnd: f64[256, 64, 16] = empty((256, 64, 16)) + arraynd: f64[200, 64, 16] = empty((200, 64, 16), dtype=float64) + sinnd: f64[200, 64, 16] = empty((200, 64, 16), dtype=float64) - for i in range(256): + for i in range(200): for j in range(64): for k in range(16): arraynd[i, j, k] = float(i + j + k) sinnd = sin(arraynd)**2.0 - verifynd(arraynd, sinnd, 256, 64, 16) + verifynd(arraynd, sinnd, 200, 64, 16) def elemental_cos(): i: i32 j: i32 - array2d: f64[256, 64] = empty((256, 64)) - cos2d: f64[256, 64] = empty((256, 64)) + array2d: f64[256, 64] = empty((256, 64), dtype=float64) + cos2d: f64[256, 64] = empty((256, 64), dtype=float64) for i in range(256): for j in range(64): @@ -138,9 +138,9 @@ def elemental_trig_identity(): eps: f32 eps = f32(1e-6) - arraynd: f32[64, 32, 8, 4] = empty((64, 32, 8, 4)) - observed: f32[64, 32, 8, 4] = empty((64, 32, 8, 4)) - observed1d: f32[65536] = empty(65536) + arraynd: f32[64, 32, 8, 4] = empty((64, 32, 8, 4), dtype=float32) + observed: f32[64, 32, 8, 4] = empty((64, 32, 8, 4), dtype=float32) + observed1d: f32[65536] = empty(65536, dtype=float32) for i in range(64): for j in range(32): @@ -150,7 +150,7 @@ def elemental_trig_identity(): observed = sin(arraynd)**f32(2) + cos(arraynd)**f32(2) - newshape: i32[1] = empty(1, dtype=int) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 65536 observed1d = reshape(observed, newshape) @@ -162,4 +162,4 @@ def elemental_trig_identity(): elemental_cos() elemental_trig_identity() elemental_sum() -elemental_mul() +elemental_mul() \ No newline at end of file diff --git a/integration_tests/elemental_02.py b/integration_tests/elemental_02.py index 0d574b76f4..e0df66ea50 100644 --- a/integration_tests/elemental_02.py +++ b/integration_tests/elemental_02.py @@ -1,12 +1,12 @@ -from ltypes import i32, f64, f32 -from numpy import empty, tan, sin, cos, reshape +from lpython import i32, f64, f32 +from numpy import empty, tan, sin, cos, reshape, int32, float32, float64 def elemental_tan64(): - theta: f64[16, 8, 4, 2, 1] = empty((16, 8, 4, 2, 1)) - theta1d: f64[1024] = empty(1024) - tantheta: f64[16, 8, 4, 2, 1] = empty((16, 8, 4, 2, 1)) - observed: f64[16, 8, 4, 2, 1] = empty((16, 8, 4, 2, 1)) - shapend: i32[5] = empty(5, dtype=int) + theta: f64[16, 8, 4, 2, 1] = empty((16, 8, 4, 2, 1), dtype=float64) + theta1d: f64[1024] = empty(1024, dtype=float64) + tantheta: f64[16, 8, 4, 2, 1] = empty((16, 8, 4, 2, 1), dtype=float64) + observed: f64[16, 8, 4, 2, 1] = empty((16, 8, 4, 2, 1), dtype=float64) + shapend: i32[5] = empty(5, dtype=int32) i: i32 j: i32 k: i32 @@ -31,15 +31,15 @@ def elemental_tan64(): assert abs(tantheta[i, j, k, l, 0] - observed[i, j, k, l, 0]) <= eps def elemental_tan32(): - theta: f32[5, 5] = empty((5, 5)) - theta1d: f32[25] = empty(25) - tantheta: f32[5, 5] = empty((5, 5)) - observed: f32[5, 5] = empty((5, 5)) - shapend: i32[2] = empty(2, dtype=int) + theta: f32[5, 5] = empty((5, 5), dtype=float32) + theta1d: f32[25] = empty(25, dtype=float32) + tantheta: f32[5, 5] = empty((5, 5), dtype=float32) + observed: f32[5, 5] = empty((5, 5), dtype=float32) + shapend: i32[2] = empty(2, dtype=int32) i: i32 j: i32 eps: f32 - eps = f32(1e-6) + eps = f32(1e-4) for i in range(25): theta1d[i] = f32(i + 1) diff --git a/integration_tests/elemental_03.py b/integration_tests/elemental_03.py index 31ae3b6efb..2638505344 100644 --- a/integration_tests/elemental_03.py +++ b/integration_tests/elemental_03.py @@ -1,10 +1,10 @@ -from ltypes import i32, f32, f64 -from numpy import empty, sqrt, reshape +from lpython import i32, f32, f64 +from numpy import empty, sqrt, reshape, int32, float32, float64 def elemental_sqrt64(): - array: f64[16, 16, 16] = empty((16, 16, 16)) - observed: f64[4096] = empty(4096) - shape: i32[1] = empty(1, dtype=int) + array: f64[16, 16, 16] = empty((16, 16, 16), dtype=float64) + observed: f64[4096] = empty(4096, dtype=float64) + shape: i32[1] = empty(1, dtype=int32) eps: f64 eps = 1e-12 i: i32 @@ -20,17 +20,17 @@ def elemental_sqrt64(): shape[0] = 4096 observed = reshape(sqrt(array), shape) for l in range(4096): - i = i32(int(l/256)) + i = i32(l/256) j = (l - i*256)//16 k = (l - i*256 - j*16) assert abs(observed[l]**2.0 - f64(i + j + k)) <= eps def elemental_sqrt32(): - array: f32[16, 16] = empty((16, 16)) - observed: f32[256] = empty(256) - shape: i32[1] = empty(1, dtype=int) + array: f32[16, 16] = empty((16, 16), dtype=float32) + observed: f32[256] = empty(256, dtype=float32) + shape: i32[1] = empty(1, dtype=int32) eps: f32 - eps = f32(2e-6) + eps = f32(5e-6) i: i32 j: i32 l: i32 @@ -42,15 +42,15 @@ def elemental_sqrt32(): shape[0] = 256 observed = reshape(sqrt(array), shape) for l in range(256): - i = i32(int(l/16)) + i = i32(l/16) j = (l - i*16) assert abs(observed[l]**f32(2.0) - f32(i + j)) <= eps def elemental_norm(): - array_a: f64[100] = empty(100) - array_b: f64[100] = empty(100) - array_c: f64[100] = empty(100) + array_a: f64[100] = empty(100, dtype=float64) + array_b: f64[100] = empty(100, dtype=float64) + array_c: f64[100] = empty(100, dtype=float64) i: i32 j: i32 diff --git a/integration_tests/elemental_04.py b/integration_tests/elemental_04.py index 56c7dcd0ff..d51e5d7a4f 100644 --- a/integration_tests/elemental_04.py +++ b/integration_tests/elemental_04.py @@ -1,10 +1,10 @@ -from ltypes import i32, f32, f64 -from numpy import empty, log, log10, log2, reshape +from lpython import i32, f32, f64 +from numpy import empty, log, log10, log2, reshape, int32, float32, float64 from math import exp def elemental_log(): - array: f64[100] = empty(100) - observed: f64[100] = empty(100) + array: f64[100] = empty(100, dtype=float64) + observed: f64[100] = empty(100, dtype=float64) i: i32 eps: f64 eps = 1e-12 @@ -23,18 +23,18 @@ def verify(observed: f32[:], base: i32, eps: f32): j: i32 for k in range(100): - i = i32(int(k/10)) + i = i32(k/10) j = (k - i*10) assert abs(f32(base)**(observed[k]) - f32(i + j + 1)) <= eps def elemental_log2_log10(): - array: f32[10, 10] = empty((10, 10)) - observed: f32[100] = empty(100) - shape: i32[1] = empty(1, dtype=int) + array: f32[10, 10] = empty((10, 10), dtype=float32) + observed: f32[100] = empty(100, dtype=float32) + shape: i32[1] = empty(1, dtype=int32) i: i32 j: i32 eps: f32 - eps = f32(2e-6) + eps = f32(5e-6) for i in range(10): for j in range(10): diff --git a/integration_tests/elemental_05.py b/integration_tests/elemental_05.py index 49b80b72ef..4e91b8eaa2 100644 --- a/integration_tests/elemental_05.py +++ b/integration_tests/elemental_05.py @@ -1,5 +1,5 @@ -from ltypes import i32, f64, f32 -from numpy import empty, sinh, cosh, reshape, int32, float64, sin +from lpython import i32, f64, f32 +from numpy import empty, sinh, cosh, reshape, int32, float32, float64, sin def verify1d(array: f32[:], result: f32[:], size: i32): i: i32 @@ -18,14 +18,14 @@ def verifynd(array: f64[:, :, :, :], result: f64[:, :, :, :], size1: i32, size2: result1d: f64[12800] = reshape(result, shape) for i in range(size): - assert abs((sinh(array1d[i]) + 2.0)/2 - result1d[i]) <= eps + assert abs((sinh(array1d[i]) + 2.0)/2.0 - result1d[i]) <= eps def elemental_sinh(): i: i32; j: i32; k: i32; l: i32; size: i32; - array1d: f32[10] = empty(10) - sinh1d: f32[10] = empty(10) + array1d: f32[10] = empty(10, dtype=float32) + sinh1d: f32[10] = empty(10, dtype=float32) for i in range(10): array1d[i] = f32(f64(i)/10.0) @@ -33,15 +33,15 @@ def elemental_sinh(): sinh1d = sinh(sinh(array1d)) verify1d(array1d, sinh1d, 10) - arraynd: f64[40, 10, 16, 2] = empty((40, 10, 16, 2)) - sinhnd: f64[40, 10, 16, 2] = empty((40, 10, 16, 2)) + arraynd: f64[40, 10, 16, 2] = empty((40, 10, 16, 2), dtype=float64) + sinhnd: f64[40, 10, 16, 2] = empty((40, 10, 16, 2), dtype=float64) size = 40 * 10 * 16 * 2 for i in range(40): for j in range(10): for k in range(16): for l in range(2): - arraynd[i, j, k, l] = float(i + 2*j + 3*k + 4*k)/size + arraynd[i, j, k, l] = float(i + 2*j + 3*k + 4*k)/float(size) sinhnd = (sinh(arraynd) + 2.0)/2.0 @@ -58,12 +58,12 @@ def verify2d(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32): def elemental_cosh(): i: i32; j: i32 - array2d: f64[20, 10] = empty((20, 10)) - cosh2d: f64[20, 10] = empty((20, 10)) + array2d: f64[20, 10] = empty((20, 10), dtype=float64) + cosh2d: f64[20, 10] = empty((20, 10), dtype=float64) for i in range(20): for j in range(10): - array2d[i, j] = (i + 2*j)/200.0 + array2d[i, j] = float(i + 2*j)/200.0 cosh2d = cosh(5.0 + (array2d))**2.0 verify2d(array2d, cosh2d, 20, 10) @@ -72,12 +72,12 @@ def elemental_cosh_(): i: i32 j: i32 - array2d: f64[20, 10] = empty((20, 10)) - cosh2d: f64[20, 10] = empty((20, 10)) + array2d: f64[20, 10] = empty((20, 10), dtype=float64) + cosh2d: f64[20, 10] = empty((20, 10), dtype=float64) for i in range(20): for j in range(10): - array2d[i, j] = (i + 2*j)/200.0 + array2d[i, j] = float(i + 2*j)/200.0 cosh2d = cosh(5.0 + (array2d))**2.0 verify2d(array2d, cosh2d, 20, 10) @@ -111,7 +111,7 @@ def elemental_trig_identity(): cosh(arraynd/4.0) * cosh(arraynd/2.0) - sinh(arraynd/4.0) * sinh(arraynd/2.0)) - newshape: i32[1] = empty(1, dtype=int) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 400 observed1d_1 = reshape(identity1, newshape) diff --git a/integration_tests/elemental_06.py b/integration_tests/elemental_06.py index 4acc162e47..13782bdb14 100644 --- a/integration_tests/elemental_06.py +++ b/integration_tests/elemental_06.py @@ -1,5 +1,5 @@ -from ltypes import i32, f32, f64 -from numpy import empty, arcsin, arccos, sin, cos, sqrt, arctan, tan, degrees, radians +from lpython import i32, f32, f64 +from numpy import empty, arcsin, arccos, sin, cos, sqrt, arctan, tan, degrees, radians, hypot, float32, float64 from math import pi def verify1d_same(array: f32[:], result: f32[:], size: i32): @@ -57,18 +57,27 @@ def verify_arctan_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): for j in range(size2): assert abs(arctan(array[i, j])**2.0 - result[i, j]) <= eps +def verify_hypot_2d(array1: f64[:, :], array2: f64[:, :], result: f64[:, :], size1:i32, size2:i32): + i: i32 + j: i32 + eps: f64 + eps = 1e-12 + for i in range(size1): + for j in range(size2): + assert abs(hypot(array1[i, j], array2[i, j]) - result[i, j]) <= eps + def elemental_arcsin(): i: i32 j: i32 - array1d: f32[201] = empty(201) - arcsin1d: f32[201] = empty(201) + array1d: f32[201] = empty(201, dtype=float32) + arcsin1d: f32[201] = empty(201, dtype=float32) for i in range(201): array1d[i] = f32((i - 100)/100) arcsin1d = arcsin(array1d) ** f32(2.0) verify_arcsin_1d(array1d, arcsin1d, 201) - array2d: f64[64, 64] = empty((64, 64)) - arcsin2d: f64[64, 64] = empty((64, 64)) + array2d: f64[64, 64] = empty((64, 64), dtype=float64) + arcsin2d: f64[64, 64] = empty((64, 64), dtype=float64) for i in range(64): for j in range(64): # 2048 = 64 * 32 array2d[i,j]= float((i * 64 + j - 2048 )/2048) @@ -79,15 +88,15 @@ def elemental_arcsin(): def elemental_arccos(): i: i32 j: i32 - array1d: f32[201] = empty(201) - arccos1d: f32[201] = empty(201) + array1d: f32[201] = empty(201, dtype=float32) + arccos1d: f32[201] = empty(201, dtype=float32) for i in range(201): array1d[i] = f32((i - 100)/100) arccos1d = arccos(array1d) ** f32(2.0) verify_arccos_1d(array1d, arccos1d, 201) - array2d: f64[64, 64] = empty((64, 64)) - arccos2d: f64[64, 64] = empty((64, 64)) + array2d: f64[64, 64] = empty((64, 64), dtype=float64) + arccos2d: f64[64, 64] = empty((64, 64), dtype=float64) for i in range(64): for j in range(64): # 2048 = 64 * 32 array2d[i,j]= float((i * 64 + j - 2048 )/2048) @@ -100,9 +109,9 @@ def elemental_arctan(): j: i32 eps: f32 eps = f32(1e-6) - array1d: f32[201] = empty(201) - array1d_rec: f32[201] = empty(201) - arctan1d: f32[201] = empty(201) + array1d: f32[201] = empty(201, dtype=float32) + array1d_rec: f32[201] = empty(201, dtype=float32) + arctan1d: f32[201] = empty(201, dtype=float32) for i in range(201): array1d[i] = f32(i - 100) arctan1d = arctan(array1d) ** f32(2.0) @@ -110,13 +119,13 @@ def elemental_arctan(): for i in range(201): array1d[i] = f32(i + 1) - array1d_rec[i] = f32(1.0/(i+1)) + array1d_rec[i] = f32(1.0/f64(i+1)) arctan1d = arctan(array1d) + arctan(array1d_rec) for i in range(201): assert abs(arctan1d[i] - f32(f64(pi) / 2.0)) <= eps - array2d: f64[64, 64] = empty((64, 64)) - arctan2d: f64[64, 64] = empty((64, 64)) + array2d: f64[64, 64] = empty((64, 64), dtype=float64) + arctan2d: f64[64, 64] = empty((64, 64), dtype=float64) for i in range(64): for j in range(64): array2d[i,j]= float(64*i + j - 2048) @@ -128,8 +137,8 @@ def elemental_trig_identity(): i: i32 eps: f32 eps = f32(1e-6) - array1d: f32[201] = empty(201) - observed1d: f32[201] = empty(201) + array1d: f32[201] = empty(201, dtype=float32) + observed1d: f32[201] = empty(201, dtype=float32) for i in range(201): array1d[i] = f32((i - 100)/100) @@ -139,8 +148,8 @@ def elemental_trig_identity(): def elemental_reverse(): i: i32 - array1d: f32[201] = empty(201) - observed1d: f32[201] = empty(201) + array1d: f32[201] = empty(201, dtype=float32) + observed1d: f32[201] = empty(201, dtype=float32) for i in range(201): array1d[i] = f32((i - 100)/100) observed1d = sin(arcsin(array1d)) @@ -157,9 +166,9 @@ def elemental_reverse(): def elemental_trig_identity_extra(): i: i32 - array1d: f32[201] = empty(201) - array_x: f32[201] = empty(201) - array_y: f32[201] = empty(201) + array1d: f32[201] = empty(201, dtype=float32) + array_x: f32[201] = empty(201, dtype=float32) + array_y: f32[201] = empty(201, dtype=float32) for i in range(201): array1d[i] = f32((i - 100)/100) array_x = sin(arccos(array1d)) @@ -177,8 +186,8 @@ def elemental_degrees(): eps_64: f64 eps_32 = f32(1e-6) eps_64 = 1e-12 - array1d: f32[200] = empty(200) - degrees1d: f32[200] = empty(200) + array1d: f32[200] = empty(200, dtype=float32) + degrees1d: f32[200] = empty(200, dtype=float32) for i in range(200): array1d[i] = f32(i) degrees1d = sin(degrees(array1d)) @@ -186,8 +195,8 @@ def elemental_degrees(): for i in range(200): assert abs(degrees1d[i] - sin(degrees(array1d[i]))) <= eps_32 - array2d: f64[64, 64] = empty((64, 64)) - degrees2d: f64[64, 64] = empty((64, 64)) + array2d: f64[64, 64] = empty((64, 64), dtype=float64) + degrees2d: f64[64, 64] = empty((64, 64), dtype=float64) for i in range(64): for j in range(64): array2d[i,j]= float(i*64+j) @@ -203,8 +212,8 @@ def elemental_radians(): eps_64: f64 eps_32 = f32(1e-6) eps_64 = 1e-12 - array1d: f32[200] = empty(200) - radians1d: f32[200] = empty(200) + array1d: f32[200] = empty(200, dtype=float32) + radians1d: f32[200] = empty(200, dtype=float32) for i in range(200): array1d[i] = f32(i) radians1d = cos(radians(array1d)) @@ -212,8 +221,8 @@ def elemental_radians(): for i in range(200): assert abs(radians1d[i] - cos(radians(array1d[i]))) <= eps_32 - array2d: f64[64, 64] = empty((64, 64)) - radians2d: f64[64, 64] = empty((64, 64)) + array2d: f64[64, 64] = empty((64, 64), dtype=float64) + radians2d: f64[64, 64] = empty((64, 64), dtype=float64) for i in range(64): for j in range(64): array2d[i,j]= float(i*64+j) @@ -222,6 +231,35 @@ def elemental_radians(): for j in range(64): assert abs(radians2d[i, j] - cos(radians(array2d[i, j]))) <= eps_64 +def elemental_hypot(): + i: i32 + j: i32 + eps_32: f32 + eps_32 = f32(1e-6) + + hypot1d: f32[200] = empty(200, dtype=float32) + array1d1: f32[200] = empty(200, dtype=float32) + array1d2: f32[200] = empty(200, dtype=float32) + for i in range(200): + array1d1[i] = f32(i) + array1d2[i] = f32(i+10) + + hypot1d = hypot(array1d1, array1d2) + + for i in range(200): + assert abs(hypot1d[i] - hypot(array1d1[i], array1d2[i])) <= eps_32 + + array2d1: f64[64, 64] = empty((64, 64), dtype=float64) + array2d2: f64[64, 64] = empty((64, 64), dtype=float64) + hypot2d: f64[64, 64] = empty((64, 64), dtype=float64) + for i in range(64): + for j in range(64): + array2d1[i,j]= float(i * j) + array2d2[i,j]= float(64*i + j - 2048) + + hypot2d = hypot(array2d1, array2d2) + verify_hypot_2d(array2d1, array2d2, hypot2d, 64, 64) + elemental_arcsin() elemental_arccos() @@ -231,3 +269,4 @@ def elemental_radians(): elemental_trig_identity() elemental_reverse() elemental_trig_identity_extra() +elemental_hypot() diff --git a/integration_tests/elemental_07.py b/integration_tests/elemental_07.py index 44dd996d00..b458eab989 100644 --- a/integration_tests/elemental_07.py +++ b/integration_tests/elemental_07.py @@ -1,5 +1,5 @@ -from ltypes import i32, f64, f32 -from numpy import empty, tanh, reshape, int32, float64, sin, log10 +from lpython import i32, f64, f32 +from numpy import empty, tanh, reshape, int32, float32, float64, sin def verify1d(array: f32[:], result: f32[:], size: i32): i: i32 @@ -24,8 +24,8 @@ def verifynd(array: f64[:, :, :, :], result: f64[:, :, :, :], size1: i32, size2: def elemental_tanh(): i: i32; j: i32; k: i32; l: i32; size: i32; - array1d: f32[80] = empty(80) - tanh1d: f32[80] = empty(80) + array1d: f32[80] = empty(80, dtype=float32) + tanh1d: f32[80] = empty(80, dtype=float32) for i in range(80): array1d[i] = f32(f64(i) / 10.0) @@ -33,15 +33,15 @@ def elemental_tanh(): tanh1d = tanh(sin(array1d)) verify1d(array1d, tanh1d, 10) - arraynd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2)) - tanhnd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2)) + arraynd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2), dtype=float64) + tanhnd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2), dtype=float64) size = 16 * 8 * 4 * 2 for i in range(16): for j in range(8): for k in range(4): for l in range(2): - arraynd[i, j, k, l] = float(i + 2*j + 3*k + 4*k)/size + arraynd[i, j, k, l] = float(i + 2*j + 3*k + 4*k)/float(size) tanhnd = (tanh(sin(arraynd)) + 2.0)/2.0 diff --git a/integration_tests/elemental_08.py b/integration_tests/elemental_08.py index 76d74430c4..1903e93cd1 100644 --- a/integration_tests/elemental_08.py +++ b/integration_tests/elemental_08.py @@ -1,5 +1,5 @@ -from ltypes import i32, f64, f32 -from numpy import empty, reshape, int32, exp +from lpython import i32, f64, f32 +from numpy import empty, reshape, int32, float32, float64, exp def verify1d(array: f32[:], result: f32[:], size: i32): i: i32 @@ -18,13 +18,13 @@ def verifynd(array: f64[:, :, :, :], result: f64[:, :, :, :], size1: i32, size2: result1d: f64[1024] = reshape(result, shape) for i in range(size): - assert abs(( exp(array1d[i]) + exp(array1d[i] / 3) ) / 2 - result1d[i]) <= eps + assert abs(( exp(array1d[i]) + exp(array1d[i] / 3.0) ) / float(2) - result1d[i]) <= eps def elemental_exp(): i: i32; j: i32; k: i32; l: i32; size: i32; - array1d: f32[80] = empty(80) - exp1d: f32[80] = empty(80) + array1d: f32[80] = empty(80, dtype=float32) + exp1d: f32[80] = empty(80, dtype=float32) for i in range(80): array1d[i] = f32(f64(i) / 50.0) @@ -32,15 +32,15 @@ def elemental_exp(): exp1d = exp(array1d) verify1d(array1d, exp1d, 80) - arraynd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2)) - expnd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2)) + arraynd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2), dtype=float64) + expnd: f64[16, 8, 4, 2] = empty((16, 8, 4, 2), dtype=float64) size = 32 for i in range(16): for j in range(8): for k in range(4): for l in range(2): - arraynd[i, j, k, l] = float( f64(i) / 8.0 + f64(j) / 4.0 + f64(k) / 2.0 + f64(l) ) / size + arraynd[i, j, k, l] = float( f64(i) / 8.0 + f64(j) / 4.0 + f64(k) / 2.0 + f64(l) ) / float(size) expnd = (exp(arraynd) + exp(arraynd / 3.0)) / 2.0 diff --git a/integration_tests/elemental_09.py b/integration_tests/elemental_09.py index fb840234cb..c879d0e926 100644 --- a/integration_tests/elemental_09.py +++ b/integration_tests/elemental_09.py @@ -1,5 +1,5 @@ -from ltypes import i32, f64, f32 -from numpy import empty, arcsinh, arccosh, reshape, float64, sinh, sqrt, sin, cosh +from lpython import i32, f64, f32 +from numpy import empty, arcsinh, arccosh, reshape, int32, float32, float64, sinh, sqrt, sin def verify1d_arcsinh(array: f32[:], result: f32[:], size: i32): i: i32 @@ -27,8 +27,8 @@ def elemental_arcsinh(): j: i32 k: i32 - array1d: f32[256] = empty(256) - arcsinh1d: f32[256] = empty(256) + array1d: f32[256] = empty(256, dtype=float32) + arcsinh1d: f32[256] = empty(256, dtype=float32) for i in range(256): array1d[i] = f32(i) @@ -36,16 +36,16 @@ def elemental_arcsinh(): arcsinh1d = arcsinh(arcsinh(array1d)) verify1d_arcsinh(array1d, arcsinh1d, 256) - arraynd: f64[256, 64, 16] = empty((256, 64, 16)) - arcsinhnd: f64[256, 64, 16] = empty((256, 64, 16)) + arraynd: f64[256, 64, 4] = empty((256, 64, 4), dtype=float64) + arcsinhnd: f64[256, 64, 4] = empty((256, 64, 4), dtype=float64) for i in range(256): for j in range(64): - for k in range(16): + for k in range(4): arraynd[i, j, k] = float(i + j + k) arcsinhnd = (1.0 + arcsinh(arraynd)) - verifynd_arcsinh(arraynd, arcsinhnd, 256, 64, 16) + verifynd_arcsinh(arraynd, arcsinhnd, 256, 64, 4) def verify2d_arccosh(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32): i: i32 @@ -77,8 +77,8 @@ def elemental_arccosh(): k: i32 l: i32 - array2d: f64[256, 64] = empty((256, 64)) - arccosh2d: f64[256, 64] = empty((256, 64)) + array2d: f64[256, 64] = empty((256, 64), dtype=float64) + arccosh2d: f64[256, 64] = empty((256, 64), dtype=float64) for i in range(256): for j in range(64): @@ -87,8 +87,8 @@ def elemental_arccosh(): arccosh2d = arccosh(array2d)**2.0 verify2d_arccosh(array2d, arccosh2d, 256, 64) - arraynd: f64[32, 16, 4, 2] = empty((32, 16, 4, 2)) - arccosh_nd: f64[32, 16, 4, 2] = empty((32, 16, 4, 2)) + arraynd: f64[32, 16, 4, 2] = empty((32, 16, 4, 2), dtype=float64) + arccosh_nd: f64[32, 16, 4, 2] = empty((32, 16, 4, 2), dtype=float64) for i in range(32): for j in range(16): @@ -126,7 +126,7 @@ def elemental_trig_identity(): identity3 = 2.0 * arcsinh(arraynd) - arccosh((arraynd**2.0) * 2.0 + 1.0) - newshape: i32[1] = empty(1, dtype=int) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 400 observed1d_1 = reshape(identity1, newshape) diff --git a/integration_tests/elemental_10.py b/integration_tests/elemental_10.py index ad742e2a13..3583d13806 100644 --- a/integration_tests/elemental_10.py +++ b/integration_tests/elemental_10.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, f64 +from lpython import i32, i64, f64 from numpy import mod, int64, empty def test_numpy_mod(): diff --git a/integration_tests/elemental_11.py b/integration_tests/elemental_11.py index 409150b2ac..ca6b111902 100644 --- a/integration_tests/elemental_11.py +++ b/integration_tests/elemental_11.py @@ -1,5 +1,5 @@ -from ltypes import i32, f64, f32 -from numpy import empty, arctanh, reshape, float64, sinh, sqrt, sin, cosh +from lpython import i32, f64, f32 +from numpy import empty, arctanh, reshape, int32, float32, float64, sinh, sqrt, sin, cosh def verify1d_arctanh(array: f32[:], result: f32[:], size: i32): i: i32 @@ -27,8 +27,8 @@ def elemental_arctanh(): j: i32 k: i32 - array1d: f32[999] = empty(999) - arctanh1d: f32[999] = empty(999) + array1d: f32[999] = empty(999, dtype=float32) + arctanh1d: f32[999] = empty(999, dtype=float32) for i in range(999): array1d[i] = f32(f64((-1)**i) * (float(i)/1000.0)) @@ -36,8 +36,8 @@ def elemental_arctanh(): arctanh1d = arctanh(array1d) verify1d_arctanh(array1d, arctanh1d, 999) - arraynd: f64[100, 50, 10] = empty((100, 50, 10)) - arctanhnd: f64[100, 50, 10] = empty((100, 50, 10)) + arraynd: f64[100, 50, 10] = empty((100, 50, 10), dtype=float64) + arctanhnd: f64[100, 50, 10] = empty((100, 50, 10), dtype=float64) for i in range(100): for j in range(50): @@ -70,7 +70,7 @@ def elemental_trig_identity(): identity1 = 2.0 * arctanh(arraynd) - arctanh((2.0 * arraynd) / ( 1.0 + arraynd**2.0)) identity2 = cosh(arctanh(arraynd)) - (sqrt(1.0 - (arraynd**2.0)))**(-1.0) - newshape: i32[1] = empty(1, dtype=int) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 400 observed1d_1 = reshape(identity1, newshape) diff --git a/integration_tests/elemental_12.py b/integration_tests/elemental_12.py index 5bfbd1b3d7..d81baf7293 100644 --- a/integration_tests/elemental_12.py +++ b/integration_tests/elemental_12.py @@ -1,5 +1,5 @@ -from ltypes import i32, f32, f64 -from numpy import empty, floor, ceil, sqrt, reshape +from lpython import i32, f32, f64 +from numpy import empty, floor, ceil, sqrt, reshape, int32, float32, float64 def elemental_floor64(): i: i32 @@ -9,9 +9,9 @@ def elemental_floor64(): eps: f32 eps = f32(1e-6) - arraynd: f64[32, 16, 8, 4] = empty((32, 16, 8, 4)) + arraynd: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) - newshape: i32[1] = empty(1, dtype=int) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 16384 for i in range(32): @@ -20,13 +20,13 @@ def elemental_floor64(): for l in range(4): arraynd[i, j, k, l] = f64((-1)**l) * sqrt(float(i + j + k + l)) - observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4)) + observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) observed = floor(arraynd) - observed1d: f64[16384] = empty(16384) + observed1d: f64[16384] = empty(16384, dtype=float64) observed1d = reshape(observed, newshape) - array: f64[16384] = empty(16384) + array: f64[16384] = empty(16384, dtype=float64) array = reshape(arraynd, newshape) for i in range(16384): @@ -41,7 +41,7 @@ def elemental_floor32(): eps: f32 eps = f32(1e-6) - arraynd: f32[32, 16, 8, 4] = empty((32, 16, 8, 4)) + arraynd: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) for i in range(32): for j in range(16): @@ -49,7 +49,7 @@ def elemental_floor32(): for l in range(4): arraynd[i, j, k, l] = f32(f64((-1)**l) * sqrt(float(i + j + k + l))) - observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4)) + observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) observed = floor(arraynd) for i in range(32): @@ -67,9 +67,9 @@ def elemental_ceil64(): eps: f32 eps = f32(1e-6) - arraynd: f64[32, 16, 8, 4] = empty((32, 16, 8, 4)) + arraynd: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) - newshape: i32[1] = empty(1, dtype=int) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 16384 for i in range(32): @@ -78,13 +78,13 @@ def elemental_ceil64(): for l in range(4): arraynd[i, j, k, l] = f64((-1)**l) * sqrt(float(i + j + k + l)) - observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4)) + observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) observed = ceil(arraynd) - observed1d: f64[16384] = empty(16384) + observed1d: f64[16384] = empty(16384, dtype=float64) observed1d = reshape(observed, newshape) - array: f64[16384] = empty(16384) + array: f64[16384] = empty(16384, dtype=float64) array = reshape(arraynd, newshape) for i in range(16384): @@ -99,7 +99,7 @@ def elemental_ceil32(): eps: f32 eps = f32(1e-6) - arraynd: f32[32, 16, 8, 4] = empty((32, 16, 8, 4)) + arraynd: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) for i in range(32): for j in range(16): @@ -107,7 +107,7 @@ def elemental_ceil32(): for l in range(4): arraynd[i, j, k, l] = f32(f64((-1)**l) * sqrt(float(i + j + k + l))) - observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4)) + observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) observed = ceil(arraynd) for i in range(32): diff --git a/integration_tests/elemental_13.py b/integration_tests/elemental_13.py new file mode 100644 index 0000000000..d0e03ea985 --- /dev/null +++ b/integration_tests/elemental_13.py @@ -0,0 +1,124 @@ +from lpython import f32, f64 +from numpy import trunc, fix, empty, sqrt, reshape, int32, float32, float64 + + +def elemental_trunc64(): + i: i32 + j: i32 + k: i32 + l: i32 + eps: f32 + eps = f32(1e-6) + + arraynd: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) + + newshape: i32[1] = empty(1, dtype = int32) + newshape[0] = 16384 + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + arraynd[i, j, k, l] = f64((-1)**l) * sqrt(float(i + j + j + l)) + + observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) + observed = trunc(arraynd) + + observed1d: f64[16384] = empty(16384, dtype=float64) + observed1d = reshape(observed, newshape) + + array: f64[16384] = empty(16384, dtype=float64) + array = reshape(arraynd, newshape) + + for i in range(16384): + assert f32(abs(trunc(array[i]) - observed1d[i])) <= eps + + +def elemental_trunc32(): + i: i32 + j: i32 + k: i32 + l: i32 + eps: f32 + eps = f32(1e-6) + + arraynd: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + arraynd[i, j, k, l] = f32(f64((-1)**l) * sqrt(float(i + j + j + l))) + + observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) + observed = trunc(arraynd) + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + assert abs(trunc(arraynd[i, j, k, l]) - observed[i, j, k, l]) <= eps + + +def elemental_fix64(): + i: i32 + j: i32 + k: i32 + l: i32 + eps: f32 + eps = f32(1e-6) + + arraynd: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) + + newshape: i32[1] = empty(1, dtype = int32) + newshape[0] = 16384 + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + arraynd[i, j, k, l] = f64((-1)**l) * sqrt(float(i + j + j + l)) + + observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) + observed = fix(arraynd) + + observed1d: f64[16384] = empty(16384, dtype=float64) + observed1d = reshape(observed, newshape) + + array: f64[16384] = empty(16384, dtype=float64) + array = reshape(arraynd, newshape) + + for i in range(16384): + assert f32(abs(fix(array[i]) - observed1d[i])) <= eps + + +def elemental_fix32(): + i: i32 + j: i32 + k: i32 + l: i32 + eps: f32 + eps = f32(1e-6) + + arraynd: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + arraynd[i, j, k, l] = f32(f64((-1)**l) * sqrt(float(i + j + j + l))) + + observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) + observed = fix(arraynd) + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + assert abs(fix(arraynd[i, j, k, l]) - observed[i, j, k, l]) <= eps + + +elemental_trunc64() +elemental_trunc32() +elemental_fix64() +elemental_fix32() diff --git a/integration_tests/enum_01.py b/integration_tests/enum_01.py index 1e2288e8c4..3c043c767e 100644 --- a/integration_tests/enum_01.py +++ b/integration_tests/enum_01.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 from enum import Enum class Color(Enum): diff --git a/integration_tests/enum_02.py b/integration_tests/enum_02.py index 5dec80442f..c36210d2dd 100644 --- a/integration_tests/enum_02.py +++ b/integration_tests/enum_02.py @@ -1,5 +1,5 @@ from enum import Enum -from ltypes import i32, f64 +from lpython import i32, f64 class MolecularMass(Enum): water: i32 = 18 diff --git a/integration_tests/enum_03.py b/integration_tests/enum_03.py index 2b82c1f32a..b087ee7426 100644 --- a/integration_tests/enum_03.py +++ b/integration_tests/enum_03.py @@ -1,5 +1,5 @@ from enum import Enum -from ltypes import i32 +from lpython import i32 class NegativeNumbers(Enum): a: i32 = -1 diff --git a/integration_tests/enum_04.py b/integration_tests/enum_04.py index 1356fe3600..4b01f3fb79 100644 --- a/integration_tests/enum_04.py +++ b/integration_tests/enum_04.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 from enum import Enum, auto class Color(Enum): diff --git a/integration_tests/enum_05.py b/integration_tests/enum_05.py index 1510aa2236..a3a424e7c9 100644 --- a/integration_tests/enum_05.py +++ b/integration_tests/enum_05.py @@ -1,4 +1,4 @@ -from ltypes import i32, ccall +from lpython import i32, ccall from enum import Enum @ccall diff --git a/integration_tests/enum_06.py b/integration_tests/enum_06.py index 70111ab890..e50a0ca0a7 100644 --- a/integration_tests/enum_06.py +++ b/integration_tests/enum_06.py @@ -1,4 +1,4 @@ -from ltypes import i32, dataclass, f64 +from lpython import i32, dataclass, f64 from numpy import empty from enum import Enum diff --git a/integration_tests/enum_07.py b/integration_tests/enum_07.py new file mode 100644 index 0000000000..204443130a --- /dev/null +++ b/integration_tests/enum_07.py @@ -0,0 +1,7 @@ +from enum_07_module import Constants + +def check(): + assert Constants.NUM_ELEMS.value == 4 + assert Constants.NUM_CHECK.value == 51 + +check() diff --git a/integration_tests/enum_07_module.py b/integration_tests/enum_07_module.py new file mode 100644 index 0000000000..a42956ec59 --- /dev/null +++ b/integration_tests/enum_07_module.py @@ -0,0 +1,6 @@ +from enum import Enum +from lpython import i32 + +class Constants(Enum): + NUM_ELEMS: i32 = 4 + NUM_CHECK: i32 = 51 diff --git a/integration_tests/exit_03.py b/integration_tests/exit_03.py new file mode 100644 index 0000000000..e7c5304c6b --- /dev/null +++ b/integration_tests/exit_03.py @@ -0,0 +1,6 @@ +def main0(): + print("Before") + quit(0) + print("After") + +main0() diff --git a/integration_tests/exit_04.py b/integration_tests/exit_04.py new file mode 100644 index 0000000000..cd27645e18 --- /dev/null +++ b/integration_tests/exit_04.py @@ -0,0 +1,6 @@ +def main0(): + print("Before") + quit(1) + print("After") + +main0() diff --git a/integration_tests/expr_01.py b/integration_tests/expr_01.py index 4baa148c68..3bd2e6b139 100644 --- a/integration_tests/expr_01.py +++ b/integration_tests/expr_01.py @@ -1,4 +1,4 @@ -from ltypes import inline, i32 +from lpython import inline, i32 @inline def add(x: i32, y: i32) -> i32: diff --git a/integration_tests/expr_01u.py b/integration_tests/expr_01u.py new file mode 100644 index 0000000000..1ae3bb52fc --- /dev/null +++ b/integration_tests/expr_01u.py @@ -0,0 +1,41 @@ +from lpython import inline, u32, u64, i64, i32, u16 + +@inline +def uadd(x: u32, y: u32) -> u32: + return x + y + +@inline +def uand_op(x: u32, y: u32) -> u32: + return x & y + +def main1(): + x: u32 + y: u32 + z: u32 + x = (u32(2)+u32(3))*u32(5) + y = uadd(x, u32(2))*u32(2) + assert x == u32(25) + assert y == u32(54) + + z = uand_op(x, y) + assert z == u32(16) + + # test issue 1867 + cycles_count: u64 + end_cycle: i64 = i64(100) + start_cycle: i64 = i64(4) + num_iters: i64 = i64(4) + cycles_count = u64((end_cycle - start_cycle) / num_iters) + assert cycles_count == u64(24) + + # test issue 1949 + x1: i32 = 20 + y1: i32 = 10 + assert u16(x1) > u16(y1) + + +main1() + +# Not implemented yet in LPython: +#if __name__ == "__main__": +# main() diff --git a/integration_tests/expr_02.py b/integration_tests/expr_02.py index af8540d83d..3b3679ba55 100644 --- a/integration_tests/expr_02.py +++ b/integration_tests/expr_02.py @@ -7,7 +7,6 @@ def main0(): b = a or True a = a or b -main0() -# Not implemented yet in LPython: -#if __name__ == "__main__": -# main() + +if __name__ == "__main__": + main0() diff --git a/integration_tests/expr_02u.py b/integration_tests/expr_02u.py new file mode 100644 index 0000000000..962c449082 --- /dev/null +++ b/integration_tests/expr_02u.py @@ -0,0 +1,78 @@ +from lpython import u8, u16, u32, u64 + +def add_u8(x: u8, y: u8) -> u8: + return x + y + +def add_u16(x: u16, y: u16) -> u16: + return x + y + +def add_u32(x: u32, y: u32) -> u32: + return x + y + +def add_u64(x: u64, y: u64) -> u64: + return x + y + +def and_u8(x: u8, y: u8) -> u8: + return x & y + +def and_u16(x: u16, y: u16) -> u16: + return x & y + +def and_u32(x: u32, y: u32) -> u32: + return x & y + +def and_u64(x: u64, y: u64) -> u64: + return x & y + +def main_u8(): + x: u8 + y: u8 + z: u8 + x = (u8(2)+u8(3))*u8(5) + y = add_u8(x, u8(2))*u8(2) + z = and_u8(x, y) + assert x == u8(25) + assert y == u8(54) + assert z == u8(16) + +def main_u16(): + x: u16 + y: u16 + z: u16 + x = (u16(2)+u16(3))*u16(5) + y = add_u16(x, u16(2))*u16(2) + z = and_u16(x, y) + assert x == u16(25) + assert y == u16(54) + assert z == u16(16) + +def main_u32(): + x: u32 + y: u32 + z: u32 + x = (u32(2)+u32(3))*u32(5) + y = add_u32(x, u32(2))*u32(2) + z = and_u32(x, y) + assert x == u32(25) + assert y == u32(54) + assert z == u32(16) + +def main_u64(): + x: u64 + y: u64 + z: u64 + x = (u64(2)+u64(3))*u64(5) + y = add_u64(x, u64(2))*u64(2) + z = and_u64(x, y) + assert x == u64(25) + assert y == u64(54) + assert z == u64(16) + +main_u8() +main_u16() +main_u32() +main_u64() + +# Not implemented yet in LPython: +#if __name__ == "__main__": +# main() diff --git a/integration_tests/expr_03.py b/integration_tests/expr_03.py index 8b673cd4ff..d22e93e9f2 100644 --- a/integration_tests/expr_03.py +++ b/integration_tests/expr_03.py @@ -1,3 +1,5 @@ +from lpython import i32 + def main0(): x: i32 x = 5 diff --git a/integration_tests/expr_03u.py b/integration_tests/expr_03u.py new file mode 100644 index 0000000000..7ab7b16de3 --- /dev/null +++ b/integration_tests/expr_03u.py @@ -0,0 +1,159 @@ +from lpython import u8, u16, u32, u64, i8, i32, TypeVar +from numpy import (empty, uint8, uint16, uint32, uint64, int8, int16, int32, + int64, size) + +n = TypeVar("n") +def add_i8(n: i32, x: i8[n], y: i8[n]) -> i8[n]: + return x + y + +def add_i8_loop(n: i32, x: i8[n], y: i8[n]) -> i8[n]: + z: i8[n] = empty(n, dtype=int8) + i: i32 + for i in range(n): + z[i] = x[i] + y[i] + return z + +def add_u8(n: i32, x: u8[n], y: u8[n]) -> u8[n]: + return x + y + +def add_u8_loop(n: i32, x: u8[n], y: u8[n]) -> u8[n]: + z: u8[n] = empty(n, dtype=uint8) + i: i32 + for i in range(n): + z[i] = x[i] + y[i] + return z + +def add_u16(n: i32, x: u16[n], y: u16[n]) -> u16[n]: + return x + y + +def add_u16_loop(n: i32, x: u16[n], y: u16[n]) -> u16[n]: + z: u16[n] = empty(n, dtype=uint16) + i: i32 + for i in range(n): + z[i] = x[i] + y[i] + return z + +def add_u32(n: i32, x: u32[n], y: u32[n]) -> u32[n]: + return x + y + +def add_u32_loop(n: i32, x: u32[n], y: u32[n]) -> u32[n]: + z: u32[n] = empty(n, dtype=uint32) + i: i32 + for i in range(n): + z[i] = x[i] + y[i] + return z + +def add_u64(n: i32, x: u64[n], y: u64[n]) -> u64[n]: + return x + y + +def add_u64_loop(n: i32, x: u64[n], y: u64[n]) -> u64[n]: + z: u64[n] = empty(n, dtype=uint64) + i: i32 + for i in range(n): + z[i] = x[i] + y[i] + return z + +def main_i8(): + x: i8[3] = empty(3, dtype=int8) + y: i8[3] = empty(3, dtype=int8) + z: i8[3] = empty(3, dtype=int8) + x[0] = i8(1) + x[1] = i8(2) + x[2] = i8(3) + y[0] = i8(2) + y[1] = i8(3) + y[2] = i8(4) + z = add_i8(size(x), x, y) + assert z[0] == i8(3) + assert z[1] == i8(5) + assert z[2] == i8(7) + z = add_i8_loop(size(x), x, y) + assert z[0] == i8(3) + assert z[1] == i8(5) + assert z[2] == i8(7) + +def main_u8(): + x: u8[3] = empty(3, dtype=uint8) + y: u8[3] = empty(3, dtype=uint8) + z: u8[3] = empty(3, dtype=uint8) + x[0] = u8(1) + x[1] = u8(2) + x[2] = u8(3) + y[0] = u8(2) + y[1] = u8(3) + y[2] = u8(4) + z = add_u8(size(x), x, y) + assert z[0] == u8(3) + assert z[1] == u8(5) + assert z[2] == u8(7) + z = add_u8_loop(size(x), x, y) + assert z[0] == u8(3) + assert z[1] == u8(5) + assert z[2] == u8(7) + +def main_u16(): + x: u16[3] = empty(3, dtype=uint16) + y: u16[3] = empty(3, dtype=uint16) + z: u16[3] = empty(3, dtype=uint16) + x[0] = u16(1) + x[1] = u16(2) + x[2] = u16(3) + y[0] = u16(2) + y[1] = u16(3) + y[2] = u16(4) + z = add_u16(size(x), x, y) + assert z[0] == u16(3) + assert z[1] == u16(5) + assert z[2] == u16(7) + z = add_u16_loop(size(x), x, y) + assert z[0] == u16(3) + assert z[1] == u16(5) + assert z[2] == u16(7) + +def main_u32(): + x: u32[3] = empty(3, dtype=uint32) + y: u32[3] = empty(3, dtype=uint32) + z: u32[3] = empty(3, dtype=uint32) + x[0] = u32(1) + x[1] = u32(2) + x[2] = u32(3) + y[0] = u32(2) + y[1] = u32(3) + y[2] = u32(4) + z = add_u32(size(x), x, y) + assert z[0] == u32(3) + assert z[1] == u32(5) + assert z[2] == u32(7) + z = add_u32_loop(size(x), x, y) + assert z[0] == u32(3) + assert z[1] == u32(5) + assert z[2] == u32(7) + +def main_u64(): + x: u64[3] = empty(3, dtype=uint64) + y: u64[3] = empty(3, dtype=uint64) + z: u64[3] = empty(3, dtype=uint64) + x[0] = u64(1) + x[1] = u64(2) + x[2] = u64(3) + y[0] = u64(2) + y[1] = u64(3) + y[2] = u64(4) + z = add_u64(size(x), x, y) + assert z[0] == u64(3) + assert z[1] == u64(5) + assert z[2] == u64(7) + z = add_u64_loop(size(x), x, y) + assert z[0] == u64(3) + assert z[1] == u64(5) + assert z[2] == u64(7) + +main_i8() +main_u8() +main_u16() +main_u32() +main_u64() + +# Not implemented yet in LPython: +#if __name__ == "__main__": +# main() diff --git a/integration_tests/expr_04.py b/integration_tests/expr_04.py index 75a16e37f0..ad46256039 100644 --- a/integration_tests/expr_04.py +++ b/integration_tests/expr_04.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64, i64 +from lpython import i32, f32, f64, i64 def main0(): i: i32 sum: i32 diff --git a/integration_tests/expr_04u.py b/integration_tests/expr_04u.py new file mode 100644 index 0000000000..5c4a22bb8d --- /dev/null +++ b/integration_tests/expr_04u.py @@ -0,0 +1,12 @@ +from lpython import u8, u16, u32, u64 + +FLAG1 : u8 = u8(1) << u8(4) +FLAG2 : u16 = u16(1) << u16(4) +FLAG3: u32 = u32(1) << u32(4) +FLAG4: u64 = u64(1) << u64(4) + +print(FLAG1, FLAG2, FLAG3, FLAG4) +assert FLAG1 == u8(16) +assert FLAG2 == u16(16) +assert FLAG3 == u32(16) +assert FLAG4 == u64(16) diff --git a/integration_tests/expr_05.py b/integration_tests/expr_05.py index 4bb65cf174..08748469b7 100644 --- a/integration_tests/expr_05.py +++ b/integration_tests/expr_05.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64 +from lpython import i32, i64, f64, u16 def test_multiply(a: i32, b: i32) -> i32: return a*b @@ -11,6 +11,8 @@ def main0(): b: i32 a = 10 b = -5 + eps: f64 + eps = 1e-12 assert test_multiply(a, b) == -50 i: i64 i = i64(1) @@ -69,6 +71,19 @@ def main0(): assert a == 0 b **= 4 assert b == 256 + # Test Issue 1562 + assert ((-8)%3) == 1 + assert ((8)%-3) == -1 + assert (-8%-3) == -2 + assert abs((11.0%-3.0) - (-1.0)) < eps + assert abs((-11.0%3.0) - (1.0)) < eps + # Test issue 1869 and 1870 + a1: u16 = u16(10) + b1: u16 = u16(3) + c1: u16 = a1 % b1 + assert c1 == u16(1) + c1 = a1 // b1 + assert c1 == u16(3) main0() diff --git a/integration_tests/expr_06.py b/integration_tests/expr_06.py index 3df110803c..566530ddb1 100644 --- a/integration_tests/expr_06.py +++ b/integration_tests/expr_06.py @@ -1,11 +1,11 @@ -from ltypes import i32, f32, f64 -from numpy import empty, cos, sin +from lpython import i32, f32, f64 +from numpy import empty, cos, sin, int32 def main0(): x: i32 = 25 y: i32 = (2 + 3) * 5 z: f32 = (f32(2.0) + f32(3)) * f32(5.0) - xa: i32[3] = empty(3) + xa: i32[3] = empty(3, dtype=int32) assert x == 25 assert y == 25 assert z == f32(25.0) diff --git a/integration_tests/expr_07.py b/integration_tests/expr_07.py index 5e78dbf46d..788fc41b58 100644 --- a/integration_tests/expr_07.py +++ b/integration_tests/expr_07.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def g(x: i32): print(x) diff --git a/integration_tests/expr_08.py b/integration_tests/expr_08.py index 1956c68c8c..0589fcee66 100644 --- a/integration_tests/expr_08.py +++ b/integration_tests/expr_08.py @@ -1,4 +1,4 @@ -from ltypes import pointer, i16, Pointer +from lpython import pointer, i16, Pointer # Testing Global Pointers x: Pointer[i16[:]] diff --git a/integration_tests/expr_09.py b/integration_tests/expr_09.py index 4fb021173f..a64e5eb35f 100644 --- a/integration_tests/expr_09.py +++ b/integration_tests/expr_09.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, f32 +from lpython import i32, f64, f32 def main0(): i1: i32 = 10 diff --git a/integration_tests/expr_10.py b/integration_tests/expr_10.py index 24da1000ee..28a715f3e0 100644 --- a/integration_tests/expr_10.py +++ b/integration_tests/expr_10.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def g() -> i32: return 5 diff --git a/integration_tests/expr_11.py b/integration_tests/expr_11.py index b72fd1b982..1e27e821b5 100644 --- a/integration_tests/expr_11.py +++ b/integration_tests/expr_11.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def f(): i: i32 diff --git a/integration_tests/expr_12.py b/integration_tests/expr_12.py index 4933a04481..2707f0122f 100644 --- a/integration_tests/expr_12.py +++ b/integration_tests/expr_12.py @@ -1,4 +1,4 @@ -from ltypes import pointer, i16, Pointer +from lpython import pointer, i16, Pointer def g(x: Pointer[i16[:]], y: i16[:]): y[0] = i16(1) diff --git a/integration_tests/expr_13.py b/integration_tests/expr_13.py index 93ed7ba446..e9c386f12c 100644 --- a/integration_tests/expr_13.py +++ b/integration_tests/expr_13.py @@ -1,4 +1,4 @@ -from ltypes import CPtr, empty_c_void_p, i32, Pointer, ccall, Const +from lpython import CPtr, empty_c_void_p, i32, Pointer, ccall, Const @ccall def deref_array(x: Pointer[CPtr], idx: i32) -> CPtr: diff --git a/integration_tests/expr_14.py b/integration_tests/expr_14.py index 7cbd452bcd..5b22fee92c 100644 --- a/integration_tests/expr_14.py +++ b/integration_tests/expr_14.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, f32, f64, c32, c64 +from lpython import i32, i64, f32, f64, c32, c64 def test_divide(): a1: i32; a2: i32; a3: f64; diff --git a/integration_tests/expr_15.py b/integration_tests/expr_15.py new file mode 100644 index 0000000000..2cf6dfa608 --- /dev/null +++ b/integration_tests/expr_15.py @@ -0,0 +1,33 @@ +from lpython import i8, i16 + +def test_issue_1586(): + x4: i16 + y4: i16 + y4 = i16(10) + x4 = i16(12345) + assert x4//y4 == i16(1234) + + a4: i8 + b4: i8 + a4 = i8(10) + b4 = i8(123) + assert b4//a4 == i8(12) + +def test_issue_1619(): + a: i16 + b: i16 + a = i16(10) + b = i16(12345) + assert b%a == i16(5) + + c: i8 + d: i8 + c = i8(10) + d = i8(123) + assert d%c == i8(3) + +def check(): + test_issue_1586() + test_issue_1619() + +check() diff --git a/integration_tests/expr_16.py b/integration_tests/expr_16.py new file mode 100644 index 0000000000..9a831d3765 --- /dev/null +++ b/integration_tests/expr_16.py @@ -0,0 +1,22 @@ +from lpython import f64, Pointer, c_p_pointer, ccall, i32, CPtr, sizeof +from numpy import array + +@ccall +def _lfortran_malloc(size: i32) -> CPtr: + pass + +def foo(xs_ptr: CPtr, length: i32) -> None: + xs: Pointer[f64[:]] = c_p_pointer(xs_ptr, f64[:], array([length])) + xs[0] = 3.0 + xs[1] = 4.0 + +def main() -> None: + length: i32 = 32 + xs_ptr: CPtr = _lfortran_malloc(length * i32(sizeof(f64))) + foo(xs_ptr, length) + t: Pointer[f64[:]] = c_p_pointer(xs_ptr, f64[:], array([32])) + print(t[0], t[1]) + assert t[0] == 3.0 + assert t[1] == 4.0 + +main() diff --git a/integration_tests/expr_17.py b/integration_tests/expr_17.py new file mode 100644 index 0000000000..eea47d9459 --- /dev/null +++ b/integration_tests/expr_17.py @@ -0,0 +1,16 @@ +from lpython import i32, f64 + +def main0(): + a: i32 = 4 + b: i32 = 3 + c: i32 = 12 + assert a * b == c, a * b + + d: f64 = 0.4 + e: f64 = 2.5 + f: f64 = 1.0 + assert abs((d * e) - f) <= 1e-6, abs((d * e) - f) + + assert a == b + 1, "Failed: a == b + 1" + +main0() diff --git a/integration_tests/expr_18.py b/integration_tests/expr_18.py new file mode 100644 index 0000000000..edfb17c327 --- /dev/null +++ b/integration_tests/expr_18.py @@ -0,0 +1,9 @@ +from lpython import i32, f64 + +def main0(): + a: i32 = 4 + b: i32 = 3 + c: i32 = 12 + assert a * b != c, "Error: 3 * 4 equals 12" + +main0() diff --git a/integration_tests/expr_19.py b/integration_tests/expr_19.py new file mode 100644 index 0000000000..6fe7a95998 --- /dev/null +++ b/integration_tests/expr_19.py @@ -0,0 +1,7 @@ +from lpython import (f64,) + +result : f64 = f64(14) +divisor : f64 = f64(4) +result /= divisor + +assert abs(result - f64(3.5)) < 1e-12 diff --git a/integration_tests/expr_20.py b/integration_tests/expr_20.py new file mode 100644 index 0000000000..f12636e845 --- /dev/null +++ b/integration_tests/expr_20.py @@ -0,0 +1,16 @@ +from lpython import i16, i32 + +def f(): + i: i32 = 5 + print(i16(i % 1023)) + +def u16(x: i16) -> i32: + if x >= i16(0): + return i32(x) + else: + return i32(x) + 65536 + +f() +print(u16(i16(10)), u16(i16(-10))) +assert(u16(i16(10)) == 10) +assert(u16(i16(-10)) == 65526) diff --git a/integration_tests/expr_21.py b/integration_tests/expr_21.py new file mode 100644 index 0000000000..e07693c580 --- /dev/null +++ b/integration_tests/expr_21.py @@ -0,0 +1,21 @@ +from lpython import i8, i16, i32, i64 + +def main0(): + x: i8 + y: i16 + z: i32 + w: i64 + + x = i8(97) + y = i16(47) + z = 56 + w = i64(67) + + print(chr(x), chr(y), chr(z), chr(w)) + + assert chr(x) == 'a' + assert chr(y) == '/' + assert chr(z) == '8' + assert chr(w) == 'C' + +main0() diff --git a/integration_tests/expr_22.py b/integration_tests/expr_22.py new file mode 100644 index 0000000000..5b61bebc35 --- /dev/null +++ b/integration_tests/expr_22.py @@ -0,0 +1,10 @@ +from lpython import f64 + +# test issue 1671 +def test_fast_fma() -> f64: + a : f64 = 5.00 + a = a + a * 10.00 + assert abs(a - 55.00) < 1e-12 + return a + +print(test_fast_fma()) diff --git a/integration_tests/expr_23.py b/integration_tests/expr_23.py new file mode 100644 index 0000000000..5aa5244d8a --- /dev/null +++ b/integration_tests/expr_23.py @@ -0,0 +1,23 @@ +from lpython import f32, i32 + +def flip_sign_check(): + x: f32 + eps: f32 = f32(1e-5) + + number: i32 = 123 + x = f32(5.5) + + if (number%2 == 1): + x = -x + + assert abs(x - f32(-5.5)) < eps + + number = 124 + x = f32(5.5) + + if (number%2 == 1): + x = -x + + assert abs(x - f32(5.5)) < eps + +flip_sign_check() diff --git a/integration_tests/expr_24.py b/integration_tests/expr_24.py new file mode 100644 index 0000000000..a616e2cc33 --- /dev/null +++ b/integration_tests/expr_24.py @@ -0,0 +1,77 @@ +from lpython import i32, f64, TypeVar, Const +from numpy import empty, int32 + +h = TypeVar("h") +w = TypeVar("w") + +def show_img(w: i32, h: i32, A: i32[h, w]): + print(w, h) + print(A[0, 0]) + print(A[h - 1, w - 1]) + + assert w == 600 + assert h == 450 + assert A[0, 0] == 254 + assert A[h - 1, w - 1] == 254 + +def show_img_color(w: i32, h: i32, A: i32[h, w, 4]): + print(w, h) + print(A[0, 0, 0]) + print(A[h - 1, w - 1, 3]) + + assert w == 600 + assert h == 450 + assert A[0, 0, 0] == 214 + assert A[h - 1, w - 1, 3] == 255 + +def main0(): + Nx: Const[i32] = 600; Ny: Const[i32] = 450; Nz: Const[i32] = 4; n_max: i32 = 255 + + xcenter: f64 = f64(-0.5); ycenter: f64 = f64(0.0) + width: f64 = f64(4); height: f64 = f64(3) + dx_di: f64 = width/f64(Nx); dy_dj: f64 = -height/f64(Ny) + x_offset: f64 = xcenter - f64(Nx+1)*dx_di/f64(2.0) + y_offset: f64 = ycenter - f64(Ny+1)*dy_dj/f64(2.0) + + i: i32; j: i32; n: i32; idx: i32 + x: f64; y: f64; x_0: f64; y_0: f64; x_sqr: f64; y_sqr: f64 + + image: i32[450, 600] = empty([Ny, Nx], dtype=int32) + image_color: i32[450, 600, 4] = empty([Ny, Nx, Nz], dtype=int32) + palette: i32[4, 3] = empty([4, 3], dtype=int32) + + for j in range(Ny): + y_0 = y_offset + dy_dj * f64(j + 1) + for i in range(Nx): + x_0 = x_offset + dx_di * f64(i + 1) + x = 0.0; y = 0.0; n = 0 + while(True): + x_sqr = x ** 2.0 + y_sqr = y ** 2.0 + if (x_sqr + y_sqr > f64(4) or n == n_max): + image[j,i] = 255 - n + break + y = y_0 + f64(2.0) * x * y + x = x_0 + x_sqr - y_sqr + n = n + 1 + + palette[0,0] = 0; palette[0,1] = 135; palette[0,2] = 68 + palette[1,0] = 0; palette[1,1] = 87; palette[1,2] = 231 + palette[2,0] = 214; palette[2,1] = 45; palette[2,2] = 32 + palette[3,0] = 255; palette[3,1] = 167; palette[3,2] = 0 + + for j in range(Ny): + for i in range(Nx): + idx = image[j,i] - i32(image[j,i]/4)*4 + image_color[j,i,0] = palette[idx,0] # Red + image_color[j,i,1] = palette[idx,1] # Green + image_color[j,i,2] = palette[idx,2] # Blue + image_color[j,i,3] = 255 # Alpha + + print("The Mandelbrot image in color:") + show_img_color(Nx, Ny, image_color) + print("The Mandelbrot image in grayscale:") + show_img(Nx, Ny, image) + print("Done.") + +main0() diff --git a/integration_tests/float_01.py b/integration_tests/float_01.py index fe5152d670..2826e44ea1 100644 --- a/integration_tests/float_01.py +++ b/integration_tests/float_01.py @@ -1,4 +1,4 @@ -from ltypes import f64 +from lpython import f64 def sqr(x: f64) -> f64: return x * x diff --git a/integration_tests/func_01.py b/integration_tests/func_01.py new file mode 100644 index 0000000000..0230bfcac2 --- /dev/null +++ b/integration_tests/func_01.py @@ -0,0 +1,14 @@ +from lpython import i32, InOut + +def reserve(a: InOut[list[i32]], b: i32): + a.append(b) + print("user defined reserve() called") + +def main0(): + x: list[i32] = [] + reserve(x, 5) + + assert len(x) == 1 + assert x[0] == 5 + +main0() diff --git a/integration_tests/func_02.py b/integration_tests/func_02.py new file mode 100644 index 0000000000..ea4fdf5b2b --- /dev/null +++ b/integration_tests/func_02.py @@ -0,0 +1,13 @@ +from lpython import S, Out +from sympy import pi + +def func(r: Out[S]) -> None: + r = pi + +def test_func(): + z: S + func(z) + print(z) + assert z == pi + +test_func() diff --git a/integration_tests/func_dep_03.py b/integration_tests/func_dep_03.py index d65a81c487..1e39f62c6a 100644 --- a/integration_tests/func_dep_03.py +++ b/integration_tests/func_dep_03.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64 +from lpython import i32, i64 def casti32(x: i64) -> i32: y: i32 diff --git a/integration_tests/func_dep_04.py b/integration_tests/func_dep_04.py index 5319ef08d2..cb464eb716 100644 --- a/integration_tests/func_dep_04.py +++ b/integration_tests/func_dep_04.py @@ -1,5 +1,5 @@ from func_dep_04_module import manhattan_distance -from ltypes import i32 +from lpython import i32 def test_manhattan_distance(): a: i32; b: i32; c: i32; d: i32; diff --git a/integration_tests/func_dep_04_module.py b/integration_tests/func_dep_04_module.py index ec826ab60e..570d432088 100644 --- a/integration_tests/func_dep_04_module.py +++ b/integration_tests/func_dep_04_module.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def manhattan_distance(x1: i32, y1: i32, x2: i32, y2: i32) -> i32: return abs(x1 - x2) + abs(y1 - y2) diff --git a/integration_tests/func_inline_01.py b/integration_tests/func_inline_01.py index 856a04ab4a..26173b52bd 100644 --- a/integration_tests/func_inline_01.py +++ b/integration_tests/func_inline_01.py @@ -1,4 +1,4 @@ -from ltypes import i64 +from lpython import i64 def fib(n: i64) -> i64: if n < i64(2): diff --git a/integration_tests/func_inline_02.py b/integration_tests/func_inline_02.py index f093a42c7b..89331d37a7 100644 --- a/integration_tests/func_inline_02.py +++ b/integration_tests/func_inline_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, Const, inline +from lpython import i32, Const, inline @inline def f(x: i32) -> i32: diff --git a/integration_tests/func_internal_def_01.py b/integration_tests/func_internal_def_01.py new file mode 100644 index 0000000000..1c0c1d11e5 --- /dev/null +++ b/integration_tests/func_internal_def_01.py @@ -0,0 +1,11 @@ +def main(): + x: i32 + x = (2+3)*5 + print(x) + + def bar(): + assert x == 25 + + bar() + +main() diff --git a/integration_tests/func_static_01.py b/integration_tests/func_static_01.py index 0b0fbda394..c87377f36e 100644 --- a/integration_tests/func_static_01.py +++ b/integration_tests/func_static_01.py @@ -1,4 +1,4 @@ -from ltypes import i64, static +from lpython import i64, static @static def fib(n: i64) -> i64: diff --git a/integration_tests/func_static_02.py b/integration_tests/func_static_02.py index 74f802a126..85f8b0151d 100644 --- a/integration_tests/func_static_02.py +++ b/integration_tests/func_static_02.py @@ -1,4 +1,4 @@ -from ltypes import i64, static, inline +from lpython import i64, static, inline @static @inline diff --git a/integration_tests/generics_01.py b/integration_tests/generics_01.py index fd1603cf6a..c3f1357ade 100644 --- a/integration_tests/generics_01.py +++ b/integration_tests/generics_01.py @@ -1,4 +1,4 @@ -from ltypes import TypeVar, restriction, i32 +from lpython import TypeVar, restriction, i32 T = TypeVar('T') diff --git a/integration_tests/generics_02.py b/integration_tests/generics_02.py index 5e36813211..2507636102 100644 --- a/integration_tests/generics_02.py +++ b/integration_tests/generics_02.py @@ -1,8 +1,8 @@ -from ltypes import TypeVar +from lpython import TypeVar, InOut, i32 T = TypeVar('T') -def swap(x: T, y: T): +def swap(x: InOut[T], y: InOut[T]): temp: T temp = x x = y @@ -10,4 +10,20 @@ def swap(x: T, y: T): print(x) print(y) -swap(1,2) \ No newline at end of file +def main0(): + a: i32 = 5 + b: i32 = 10 + + # Invalid test case for CPython: + # CPython passes values by copy of object reference + # and hence does not support swapping variables + # passed by arguments. + # Therefore do not add asserts to this file + + print(a, b) + + swap(a, b) + + print(a, b) + +main0() diff --git a/integration_tests/generics_array_01.py b/integration_tests/generics_array_01.py index 4c733b7c4a..3ae77260ee 100644 --- a/integration_tests/generics_array_01.py +++ b/integration_tests/generics_array_01.py @@ -1,5 +1,5 @@ -from ltypes import TypeVar, i32 -from numpy import empty +from lpython import TypeVar, i32 +from numpy import empty, int32 T = TypeVar('T') @@ -9,9 +9,9 @@ def f(lst: T[:], i: T) -> T: def use_array(): array: i32[1] - array = empty(1) + array = empty(1, dtype=int32) x: i32 x = 69 print(f(array, x)) -use_array() \ No newline at end of file +use_array() diff --git a/integration_tests/generics_array_02.py b/integration_tests/generics_array_02.py index 94b23085ca..2315582ca0 100644 --- a/integration_tests/generics_array_02.py +++ b/integration_tests/generics_array_02.py @@ -1,7 +1,6 @@ -from ltypes import TypeVar, restriction, i32, f32 -from numpy import empty +from lpython import TypeVar, restriction, i32, f32 +from numpy import empty, int32, float32 -n: i32 n = TypeVar("n") T = TypeVar('T') @@ -17,21 +16,21 @@ def add_float(x: f32, y: f32) -> f32: def g(n: i32, a: T[n], b: T[n], **kwargs): r: T[n] - r = empty(n) + r = empty(n, dtype=object) i: i32 for i in range(n): r[i] = add(a[i], b[i]) print(r[0]) def main(): - a_int: i32[1] = empty(1) + a_int: i32[1] = empty(1, dtype=int32) a_int[0] = 400 - b_int: i32[1] = empty(1) + b_int: i32[1] = empty(1, dtype=int32) b_int[0] = 20 g(1, a_int, b_int, add=add_integer) - a_float: f32[1] = empty(1) + a_float: f32[1] = empty(1, dtype=float32) a_float[0] = f32(400.0) - b_float: f32[1] = empty(1) + b_float: f32[1] = empty(1, dtype=float32) b_float[0] = f32(20.0) g(1, a_float, b_float, add=add_float) diff --git a/integration_tests/generics_array_03.py b/integration_tests/generics_array_03.py index 8de3fe5908..ebc5875220 100644 --- a/integration_tests/generics_array_03.py +++ b/integration_tests/generics_array_03.py @@ -1,9 +1,7 @@ -from ltypes import TypeVar, restriction, i32, f32 -from numpy import empty +from lpython import TypeVar, restriction, i32, f32 +from numpy import empty, int32, float32 -n: i32 n = TypeVar("n") -m: i32 m = TypeVar("m") T = TypeVar('T') @@ -19,7 +17,7 @@ def add_float(x: f32, y: f32) -> f32: def g(n: i32, m: i32, a: T[n,m], b: T[n,m], **kwargs) -> T[n,m]: r: T[n,m] - r = empty([n,m]) + r = empty([n,m], dtype=object) i: i32 j: i32 for i in range(n): @@ -28,14 +26,14 @@ def g(n: i32, m: i32, a: T[n,m], b: T[n,m], **kwargs) -> T[n,m]: print(r[0,0]) def main(): - a_int: i32[1,1] = empty([1,1]) + a_int: i32[1,1] = empty([1,1], dtype=int32) a_int[0,0] = 400 - b_int: i32[1,1] = empty([1,1]) + b_int: i32[1,1] = empty([1,1], dtype=int32) b_int[0,0] = 20 g(1, 1, a_int, b_int, add=add_integer) - a_float: f32[1,1] = empty([1,1]) + a_float: f32[1,1] = empty([1,1], dtype=float32) a_float[0,0] = f32(400) - b_float: f32[1,1] = empty([1,1]) + b_float: f32[1,1] = empty([1,1], dtype=float32) b_float[0,0] = f32(20) g(1, 1, a_float, b_float, add=add_float) diff --git a/integration_tests/generics_list_01.py b/integration_tests/generics_list_01.py index ec76496b70..2d228532ce 100644 --- a/integration_tests/generics_list_01.py +++ b/integration_tests/generics_list_01.py @@ -1,4 +1,4 @@ -from ltypes import TypeVar, f64, i32, restriction +from lpython import TypeVar, f64, i32, restriction T = TypeVar('T') @@ -30,7 +30,7 @@ def add_float(x: f64, y: f64) -> f64: return x + y def div_float(x: f64, k: i32) -> f64: - return x / k + return x / f64(k) def empty_string(x: str) -> str: return "" diff --git a/integration_tests/global_syms_01.py b/integration_tests/global_syms_01.py new file mode 100644 index 0000000000..fbf9cbb97a --- /dev/null +++ b/integration_tests/global_syms_01.py @@ -0,0 +1,12 @@ +from lpython import i32 + +x: list[i32] +x = [1, 2] +i: i32 +i = x[0] + +def test_global_symbols(): + assert i == 1 + assert x[1] == 2 + +test_global_symbols() diff --git a/integration_tests/global_syms_02.py b/integration_tests/global_syms_02.py new file mode 100644 index 0000000000..840732e4cc --- /dev/null +++ b/integration_tests/global_syms_02.py @@ -0,0 +1,23 @@ +from lpython import i32 + +x: list[i32] +x = [0, 1] +x.append(3) + +def test_global_symbols(): + assert len(x) == 3 + x.insert(2, 2) + +test_global_symbols() + +i: i32 +for i in range(len(x)): + assert i == x[i] + +tmp: list[i32] +tmp = x + +tmp.remove(0) +assert len(tmp) == 3 +tmp.clear() +assert len(tmp) == 0 diff --git a/integration_tests/global_syms_03_a.py b/integration_tests/global_syms_03_a.py new file mode 100644 index 0000000000..ad8f62f759 --- /dev/null +++ b/integration_tests/global_syms_03_a.py @@ -0,0 +1,13 @@ +from lpython import i32, f64 + +print("Imported from global_syms_03_a") + +l_1: list[str] = ['Monday', 'Tuesday', 'Wednesday'] +l_1.append('Thursday') + +def populate_lists() -> list[i32]: + return [10, -20] +l_2: list[i32] = populate_lists() + +l_3: list[f64] +l_3 = [1.0, 2.0, 3.0] diff --git a/integration_tests/global_syms_03_b.py b/integration_tests/global_syms_03_b.py new file mode 100644 index 0000000000..0d77cfc79e --- /dev/null +++ b/integration_tests/global_syms_03_b.py @@ -0,0 +1,5 @@ +from global_syms_03_a import l_1, l_2 + +assert len(l_1) == 4 +assert l_1[1] == "Tuesday" +assert l_2[1] == -20 diff --git a/integration_tests/global_syms_03_c.py b/integration_tests/global_syms_03_c.py new file mode 100644 index 0000000000..cf6f05375b --- /dev/null +++ b/integration_tests/global_syms_03_c.py @@ -0,0 +1,5 @@ +import global_syms_03_a + +assert len(global_syms_03_a.l_1) == 4 +assert global_syms_03_a.l_1[3] == "Thursday" +assert global_syms_03_a.l_3 == [1.0, 2.0, 3.0] diff --git a/integration_tests/global_syms_04.py b/integration_tests/global_syms_04.py new file mode 100644 index 0000000000..7b035167e2 --- /dev/null +++ b/integration_tests/global_syms_04.py @@ -0,0 +1,37 @@ +from lpython import i32, i64, f64 + +a: str = "hi" +b: i32 = -24 +c: i64 = i64(151) +d: f64 = -68.512 + +def print_global_symbols(): + print(a) + print(b) + print(c) + print(d) + +def test_global_symbols(): + assert b == -24 + assert c == i64(151) + assert abs(d - (-68.512)) <= 1e-12 + +def update_global_symbols(): + global b, c, d + x: f64 = f64(c) * d + b = i32(x) + y: f64 = f64(b) / 12.0 + c = i64(y) + z: i64 = i64(b) * c + d = f64(z) + +def test_global_symbols_post_update(): + assert b == -10345 + assert c == i64(-862) + assert abs(d - 8917390.0) <= 1e-12 + +print_global_symbols() +test_global_symbols() +update_global_symbols() +print_global_symbols() +test_global_symbols_post_update() diff --git a/integration_tests/global_syms_05.py b/integration_tests/global_syms_05.py new file mode 100644 index 0000000000..62b97c2593 --- /dev/null +++ b/integration_tests/global_syms_05.py @@ -0,0 +1,21 @@ +from lpython import i32 + +# GLOBAL Dictionary +x: dict[i32, i32] +x = {0 : 0, 1: 1000, 2: 2000, 3 : 3000} + +x[4] = 4000 +assert len(x) == 5 +x[5] = 5000 +assert x[2] == 2000 +i: i32 +for i in range(len(x)): + assert x[i] == i * 1000 + +# Copy of Dictionary +tmp: dict[i32, i32] +tmp = x +tmp[6] = 6000 +assert len(tmp) == 7 +assert tmp[6] == 6000 +assert tmp[1] == 1000 diff --git a/integration_tests/global_syms_06.py b/integration_tests/global_syms_06.py new file mode 100644 index 0000000000..0b396d1408 --- /dev/null +++ b/integration_tests/global_syms_06.py @@ -0,0 +1,9 @@ +from lpython import i32 + +def test() -> i32: + temp: i32 = 0 + return temp + +x: i32 = test() +i: i32 = 10 +j: i32 = i diff --git a/integration_tests/gruntz_demo.py b/integration_tests/gruntz_demo.py new file mode 100644 index 0000000000..6beb38f330 --- /dev/null +++ b/integration_tests/gruntz_demo.py @@ -0,0 +1,399 @@ +""" +Limits +====== + +Implemented according to the PhD thesis +https://www.cybertester.com/data/gruntz.pdf, which contains very thorough +descriptions of the algorithm including many examples. We summarize here +the gist of it. + +All functions are sorted according to how rapidly varying they are at +infinity using the following rules. Any two functions f and g can be +compared using the properties of L: + +L=lim log|f(x)| / log|g(x)| (for x -> oo) + +We define >, < ~ according to:: + + 1. f > g .... L=+-oo + + we say that: + - f is greater than any power of g + - f is more rapidly varying than g + - f goes to infinity/zero faster than g + + 2. f < g .... L=0 + + we say that: + - f is lower than any power of g + + 3. f ~ g .... L!=0, +-oo + + we say that: + - both f and g are bounded from above and below by suitable integral + powers of the other + +Examples +======== +:: + 2 < x < exp(x) < exp(x**2) < exp(exp(x)) + 2 ~ 3 ~ -5 + x ~ x**2 ~ x**3 ~ 1/x ~ x**m ~ -x + exp(x) ~ exp(-x) ~ exp(2x) ~ exp(x)**2 ~ exp(x+exp(-x)) + f ~ 1/f + +So we can divide all the functions into comparability classes (x and x^2 +belong to one class, exp(x) and exp(-x) belong to some other class). In +principle, we could compare any two functions, but in our algorithm, we +do not compare anything below the class 2~3~-5 (for example log(x) is +below this), so we set 2~3~-5 as the lowest comparability class. + +Given the function f, we find the list of most rapidly varying (mrv set) +subexpressions of it. This list belongs to the same comparability class. +Let's say it is {exp(x), exp(2x)}. Using the rule f ~ 1/f we find an +element "w" (either from the list or a new one) from the same +comparability class which goes to zero at infinity. In our example we +set w=exp(-x) (but we could also set w=exp(-2x) or w=exp(-3x) ...). We +rewrite the mrv set using w, in our case {1/w, 1/w^2}, and substitute it +into f. Then we expand f into a series in w:: + + f = c0*w^e0 + c1*w^e1 + ... + O(w^en), where e0oo, lim f = lim c0*w^e0, because all the other terms go to zero, +because w goes to zero faster than the ci and ei. So:: + + for e0>0, lim f = 0 + for e0<0, lim f = +-oo (the sign depends on the sign of c0) + for e0=0, lim f = lim c0 + +We need to recursively compute limits at several places of the algorithm, but +as is shown in the PhD thesis, it always finishes. + +Important functions from the implementation: + +compare(a, b, x) compares "a" and "b" by computing the limit L. +mrv(e, x) returns list of most rapidly varying (mrv) subexpressions of "e" +rewrite(e, Omega, x, wsym) rewrites "e" in terms of w +leadterm(f, x) returns the lowest power term in the series of f +mrv_leadterm(e, x) returns the lead term (c0, e0) for e +limitinf(e, x) computes lim e (for x->oo) +limit(e, z, z0) computes any limit by converting it to the case x->oo + +All the functions are really simple and straightforward except +rewrite(), which is the most difficult/complex part of the algorithm. +When the algorithm fails, the bugs are usually in the series expansion +(i.e. in SymPy) or in rewrite. + +This code is almost exact rewrite of the Maple code inside the Gruntz +thesis. + +Debugging +--------- + +Because the gruntz algorithm is highly recursive, it's difficult to +figure out what went wrong inside a debugger. Instead, turn on nice +debug prints by defining the environment variable SYMPY_DEBUG. For +example: + +[user@localhost]: SYMPY_DEBUG=True ./bin/isympy + +In [1]: limit(sin(x)/x, x, 0) +limitinf(_x*sin(1/_x), _x) = 1 ++-mrv_leadterm(_x*sin(1/_x), _x) = (1, 0) +| +-mrv(_x*sin(1/_x), _x) = set([_x]) +| | +-mrv(_x, _x) = set([_x]) +| | +-mrv(sin(1/_x), _x) = set([_x]) +| | +-mrv(1/_x, _x) = set([_x]) +| | +-mrv(_x, _x) = set([_x]) +| +-mrv_leadterm(exp(_x)*sin(exp(-_x)), _x, set([exp(_x)])) = (1, 0) +| +-rewrite(exp(_x)*sin(exp(-_x)), set([exp(_x)]), _x, _w) = (1/_w*sin(_w), -_x) +| +-sign(_x, _x) = 1 +| +-mrv_leadterm(1, _x) = (1, 0) ++-sign(0, _x) = 0 ++-limitinf(1, _x) = 1 + +And check manually which line is wrong. Then go to the source code and +debug this function to figure out the exact problem. + +""" +from functools import reduce + +from sympy.core import Basic, S, Mul, PoleError, expand_mul, evaluate +from sympy.core.cache import cacheit +from sympy.core.numbers import I, oo +from sympy.core.symbol import Dummy, Wild, Symbol +from sympy.core.traversal import bottom_up +from sympy.core.sorting import ordered + +from sympy.functions import log, exp, sign, sin +from sympy.series.order import Order +from sympy.utilities.exceptions import SymPyDeprecationWarning +from sympy.utilities.misc import debug_decorator as debug +from sympy.utilities.timeutils import timethis + +def mrv(e, x): + """ + Calculate the MRV set of the expression. + + Examples + ======== + + >>> mrv(log(x - log(x))/log(x), x) + {x} + + """ + + if not e.has(x): + return set() + if e == x: + return {x} + if e.is_Mul or e.is_Add: + a, b = e.as_two_terms() + return mrv_max(mrv(a, x), mrv(b, x), x) + if e.func == exp: + if e.exp == x: + return {e} + if any(a.is_infinite for a in Mul.make_args(limitinf(e.exp, x))): + return mrv_max({e}, mrv(e.exp, x), x) + return mrv(e.exp, x) + if e.is_Pow: + return mrv(e.base, x) + if isinstance(e, log): + return mrv(e.args[0], x) + if e.is_Function: + return reduce(lambda a, b: mrv_max(a, b, x), (mrv(a, x) for a in e.args)) + raise NotImplementedError(f"Can't calculate the MRV of {e}.") + +def mrv_max(f, g, x): + """Compute the maximum of two MRV sets. + + Examples + ======== + + >>> mrv_max({log(x)}, {x**5}, x) + {x**5} + + """ + + if not f: + return g + if not g: + return f + if f & g: + return f | g + + a, b = map(next, map(iter, (f, g))) + + # The log(exp(...)) must always be simplified here. + la = a.exp if a.is_Exp else log(a) + lb = b.exp if b.is_Exp else log(b) + + c = limitinf(la/lb, x) + if c.is_zero: + return g + if c.is_infinite: + return f + return f | g + +def rewrite(e, x, w): + r""" + Rewrites the expression in terms of the MRV subexpression. + + Parameters + ========== + + e : Expr + an expression + x : Symbol + variable of the `e` + w : Symbol + The symbol which is going to be used for substitution in place + of the MRV in `x` subexpression. + + Returns + ======= + + tuple + A pair: rewritten (in `w`) expression and `\log(w)`. + + Examples + ======== + + >>> rewrite(exp(x)*log(x), x, y) + (log(x)/y, -x) + + """ + + Omega = mrv(e, x) + if not Omega: + return e, None # e really does not depend on x + + if x in Omega: + # Moving up in the asymptotical scale: + with evaluate(False): + e = e.xreplace({x: exp(x)}) + Omega = {s.xreplace({x: exp(x)}) for s in Omega} + + Omega = list(ordered(Omega, keys=lambda a: -len(mrv(a, x)))) + + for g in Omega: + sig = signinf(g.exp, x) + if sig not in (1, -1): + raise NotImplementedError(f'Result depends on the sign of {sig}.') + + if sig == 1: + w = 1/w # if g goes to oo, substitute 1/w + + # Rewrite and substitute subexpressions in the Omega. + for a in Omega: + c = limitinf(a.exp/g.exp, x) + b = exp(a.exp - c*g.exp)*w**c # exponential must never be expanded here + with evaluate(False): + e = e.xreplace({a: b}) + + return e, -sig*g.exp + +@cacheit +def mrv_leadterm(e, x): + """ + Compute the leading term of the series. + + Returns + ======= + + tuple + The leading term `c_0 w^{e_0}` of the series of `e` in terms + of the most rapidly varying subexpression `w` in form of + the pair ``(c0, e0)`` of Expr. + + Examples + ======== + + >>> leadterm(1/exp(-x + exp(-x)) - exp(x), x) + (-1, 0) + + """ + + if not e.has(x): + return e, Integer(0) + + # Rewrite to exp-log functions per Sec. 3.3 of thesis. + e = e.replace(lambda f: f.is_Pow and f.exp.has(x), + lambda f: exp(log(f.base)*f.exp)) + e = e.replace(lambda f: f.is_Mul and sum(a.func == exp for a in f.args) > 1, + lambda f: Mul(exp(Add(*(a.exp for a in f.args if a.func == exp))), + *(a for a in f.args if not a.func == exp))) + + # The positive dummy, w, is used here so log(w*2) etc. will expand. + # TODO: For limits of complex functions, the algorithm would have to + # be improved, or just find limits of Re and Im components separately. + w = Dummy('w', real=True, positive=True) + e, logw = rewrite(e, x, w) + + c0, e0 = e.leadterm(w, logx=logw) + if c0.has(w): + raise NotImplementedError(f'Cannot compute leadterm({e}, {x}). ' + 'The coefficient should have been free of ' + f'{w}, but got {c0}.') + return c0.subs(log(w), logw), e0 + +@cacheit +def signinf(e, x): + r""" + Determine sign of the expression at the infinity. + + Returns + ======= + + {1, 0, -1} + One or minus one, if `e > 0` or `e < 0` for `x` sufficiently + large and zero if `e` is *constantly* zero for `x\to\infty`. + + """ + + if not e.has(x): + return sign(e).simplify() + if e == x or (e.is_Pow and signinf(e.base, x) == 1): + return S(1) + if e.is_Mul: + a, b = e.as_two_terms() + return signinf(a, x)*signinf(b, x) + + c0, _ = leadterm(e, x) + return signinf(c0, x) + +@cacheit +def limitinf(e, x): + """ + Compute the limit of the expression at the infinity. + + Examples + ======== + + >>> limitinf(exp(x)*(exp(1/x - exp(-x)) - exp(1/x)), x) + -1 + + """ + # Rewrite e in terms of tractable functions only: + e = e.rewrite('tractable', deep=True, limitvar=x) + + if not e.has(x): + return e.rewrite('intractable', deep=True) + + c0, e0 = mrv_leadterm(e, x) + sig = signinf(e0, x) + if sig == 1: + return S(0) + if sig == -1: + return signinf(c0, x)*oo + if sig == 0: + return limitinf(c0, x) + raise NotImplementedError(f'Result depends on the sign of {sig}.') + + +def gruntz(e, z, z0, dir="+"): + """ + Compute the limit of e(z) at the point z0 using the Gruntz algorithm. + + Explanation + =========== + + ``z0`` can be any expression, including oo and -oo. + + For ``dir="+"`` (default) it calculates the limit from the right + (z->z0+) and for ``dir="-"`` the limit from the left (z->z0-). For infinite z0 + (oo or -oo), the dir argument does not matter. + + This algorithm is fully described in the module docstring in the gruntz.py + file. It relies heavily on the series expansion. Most frequently, gruntz() + is only used if the faster limit() function (which uses heuristics) fails. + """ + if not z.is_symbol: + raise NotImplementedError("Second argument must be a Symbol") + + # convert all limits to the limit z->oo; sign of z is handled in limitinf + r = None + if z0 in (oo, I*oo): + e0 = e + elif z0 in (-oo, -I*oo): + e0 = e.subs(z, -z) + else: + if str(dir) == "-": + e0 = e.subs(z, z0 - 1/z) + elif str(dir) == "+": + e0 = e.subs(z, z0 + 1/z) + else: + raise NotImplementedError("dir must be '+' or '-'") + + r = limitinf(e0, z) + + # This is a bit of a heuristic for nice results... we always rewrite + # tractable functions in terms of familiar intractable ones. + # It might be nicer to rewrite the exactly to what they were initially, + # but that would take some work to implement. + return r.rewrite('intractable', deep=True) + +# tests +x = Symbol('x') +ans = gruntz(sin(x)/x, x, 0) +print(ans) \ No newline at end of file diff --git a/integration_tests/gruntz_demo2.py b/integration_tests/gruntz_demo2.py new file mode 100644 index 0000000000..a9faead47d --- /dev/null +++ b/integration_tests/gruntz_demo2.py @@ -0,0 +1,347 @@ +""" +Limits +====== + +Implemented according to the PhD thesis +https://www.cybertester.com/data/gruntz.pdf, which contains very thorough +descriptions of the algorithm including many examples. We summarize here +the gist of it. + +All functions are sorted according to how rapidly varying they are at +infinity using the following rules. Any two functions f and g can be +compared using the properties of L: + +L=lim log|f(x)| / log|g(x)| (for x -> oo) + +We define >, < ~ according to:: + + 1. f > g .... L=+-oo + + we say that: + - f is greater than any power of g + - f is more rapidly varying than g + - f goes to infinity/zero faster than g + + 2. f < g .... L=0 + + we say that: + - f is lower than any power of g + + 3. f ~ g .... L!=0, +-oo + + we say that: + - both f and g are bounded from above and below by suitable integral + powers of the other + +Examples +======== +:: + 2 < x < exp(x) < exp(x**2) < exp(exp(x)) + 2 ~ 3 ~ -5 + x ~ x**2 ~ x**3 ~ 1/x ~ x**m ~ -x + exp(x) ~ exp(-x) ~ exp(2x) ~ exp(x)**2 ~ exp(x+exp(-x)) + f ~ 1/f + +So we can divide all the functions into comparability classes (x and x^2 +belong to one class, exp(x) and exp(-x) belong to some other class). In +principle, we could compare any two functions, but in our algorithm, we +do not compare anything below the class 2~3~-5 (for example log(x) is +below this), so we set 2~3~-5 as the lowest comparability class. + +Given the function f, we find the list of most rapidly varying (mrv set) +subexpressions of it. This list belongs to the same comparability class. +Let's say it is {exp(x), exp(2x)}. Using the rule f ~ 1/f we find an +element "w" (either from the list or a new one) from the same +comparability class which goes to zero at infinity. In our example we +set w=exp(-x) (but we could also set w=exp(-2x) or w=exp(-3x) ...). We +rewrite the mrv set using w, in our case {1/w, 1/w^2}, and substitute it +into f. Then we expand f into a series in w:: + + f = c0*w^e0 + c1*w^e1 + ... + O(w^en), where e0oo, lim f = lim c0*w^e0, because all the other terms go to zero, +because w goes to zero faster than the ci and ei. So:: + + for e0>0, lim f = 0 + for e0<0, lim f = +-oo (the sign depends on the sign of c0) + for e0=0, lim f = lim c0 + +We need to recursively compute limits at several places of the algorithm, but +as is shown in the PhD thesis, it always finishes. + +Important functions from the implementation: + +compare(a, b, x) compares "a" and "b" by computing the limit L. +mrv(e, x) returns list of most rapidly varying (mrv) subexpressions of "e" +rewrite(e, Omega, x, wsym) rewrites "e" in terms of w +leadterm(f, x) returns the lowest power term in the series of f +mrv_leadterm(e, x) returns the lead term (c0, e0) for e +limitinf(e, x) computes lim e (for x->oo) +limit(e, z, z0) computes any limit by converting it to the case x->oo + +All the functions are really simple and straightforward except +rewrite(), which is the most difficult/complex part of the algorithm. +When the algorithm fails, the bugs are usually in the series expansion +(i.e. in SymPy) or in rewrite. + +This code is almost exact rewrite of the Maple code inside the Gruntz +thesis. + +Debugging +--------- + +Because the gruntz algorithm is highly recursive, it's difficult to +figure out what went wrong inside a debugger. Instead, turn on nice +debug prints by defining the environment variable SYMPY_DEBUG. For +example: + +[user@localhost]: SYMPY_DEBUG=True ./bin/isympy + +In [1]: limit(sin(x)/x, x, 0) +limitinf(_x*sin(1/_x), _x) = 1 ++-mrv_leadterm(_x*sin(1/_x), _x) = (1, 0) +| +-mrv(_x*sin(1/_x), _x) = set([_x]) +| | +-mrv(_x, _x) = set([_x]) +| | +-mrv(sin(1/_x), _x) = set([_x]) +| | +-mrv(1/_x, _x) = set([_x]) +| | +-mrv(_x, _x) = set([_x]) +| +-mrv_leadterm(exp(_x)*sin(exp(-_x)), _x, set([exp(_x)])) = (1, 0) +| +-rewrite(exp(_x)*sin(exp(-_x)), set([exp(_x)]), _x, _w) = (1/_w*sin(_w), -_x) +| +-sign(_x, _x) = 1 +| +-mrv_leadterm(1, _x) = (1, 0) ++-sign(0, _x) = 0 ++-limitinf(1, _x) = 1 + +And check manually which line is wrong. Then go to the source code and +debug this function to figure out the exact problem. + +""" +from functools import reduce + +from sympy.core import Basic, S, Mul, PoleError, expand_mul, evaluate, Integer +from sympy.core.cache import cacheit +from sympy.core.numbers import I, oo +from sympy.core.symbol import Dummy, Wild, Symbol +from sympy.core.traversal import bottom_up +from sympy.core.sorting import ordered + +from sympy.functions import log, exp, sign, sin +from sympy.series.order import Order +from sympy.utilities.exceptions import SymPyDeprecationWarning +from sympy.utilities.misc import debug_decorator as debug +from sympy.utilities.timeutils import timethis + +def mrv(e, x): + """ + Calculate the MRV set of the expression. + + Examples + ======== + + >>> mrv(log(x - log(x))/log(x), x) + {x} + + """ + + if e == x: + return {x} + elif e.is_Integer: + return {} + elif e.is_Mul or e.is_Add: + a, b = e.as_two_terms() + ans1 = mrv(a, x) + ans2 = mrv(b, x) + return mrv_max(mrv(a, x), mrv(b, x), x) + elif e.is_Pow: + return mrv(e.base, x) + elif e.is_Function: + return reduce(lambda a, b: mrv_max(a, b, x), (mrv(a, x) for a in e.args)) + raise NotImplementedError(f"Can't calculate the MRV of {e}.") + +def mrv_max(f, g, x): + """Compute the maximum of two MRV sets. + + Examples + ======== + + >>> mrv_max({log(x)}, {x**5}, x) + {x**5} + + """ + + if not f: + return g + if not g: + return f + if f & g: + return f | g + +def rewrite(e, x, w): + r""" + Rewrites the expression in terms of the MRV subexpression. + + Parameters + ========== + + e : Expr + an expression + x : Symbol + variable of the `e` + w : Symbol + The symbol which is going to be used for substitution in place + of the MRV in `x` subexpression. + + Returns + ======= + + The rewritten expression + + Examples + ======== + + >>> rewrite(exp(x)*log(x), x, y) + (log(x)/y, -x) + + """ + + Omega = mrv(e, x) + + if x in Omega: + # Moving up in the asymptotical scale: + with evaluate(False): + e = e.subs(x, exp(x)) + Omega = {s.subs(x, exp(x)) for s in Omega} + + Omega = list(ordered(Omega, keys=lambda a: -len(mrv(a, x)))) + + for g in Omega: + sig = signinf(g.exp, x) + if sig not in (1, -1): + raise NotImplementedError(f'Result depends on the sign of {sig}.') + + if sig == 1: + w = 1/w # if g goes to oo, substitute 1/w + + # Rewrite and substitute subexpressions in the Omega. + for a in Omega: + c = limitinf(a.exp/g.exp, x) + b = exp(a.exp - c*g.exp)*w**c # exponential must never be expanded here + with evaluate(False): + e = e.xreplace({a: b}) + + return e + +@cacheit +def mrv_leadterm(e, x): + """ + Compute the leading term of the series. + + Returns + ======= + + tuple + The leading term `c_0 w^{e_0}` of the series of `e` in terms + of the most rapidly varying subexpression `w` in form of + the pair ``(c0, e0)`` of Expr. + + Examples + ======== + + >>> leadterm(1/exp(-x + exp(-x)) - exp(x), x) + (-1, 0) + + """ + + w = Dummy('w', real=True, positive=True) + e = rewrite(e, x, w) + return e.leadterm(w) + +@cacheit +def signinf(e, x): + r""" + Determine sign of the expression at the infinity. + + Returns + ======= + + {1, 0, -1} + One or minus one, if `e > 0` or `e < 0` for `x` sufficiently + large and zero if `e` is *constantly* zero for `x\to\infty`. + + """ + + if not e.has(x): + return sign(e) + if e == x or (e.is_Pow and signinf(e.base, x) == 1): + return S(1) + +@cacheit +def limitinf(e, x): + """ + Compute the limit of the expression at the infinity. + + Examples + ======== + + >>> limitinf(exp(x)*(exp(1/x - exp(-x)) - exp(1/x)), x) + -1 + + """ + + if not e.has(x): + return e + + c0, e0 = mrv_leadterm(e, x) + sig = signinf(e0, x) + if sig == 1: + return Integer(0) + if sig == -1: + return signinf(c0, x)*oo + if sig == 0: + return limitinf(c0, x) + raise NotImplementedError(f'Result depends on the sign of {sig}.') + + +def gruntz(e, z, z0, dir="+"): + """ + Compute the limit of e(z) at the point z0 using the Gruntz algorithm. + + Explanation + =========== + + ``z0`` can be any expression, including oo and -oo. + + For ``dir="+"`` (default) it calculates the limit from the right + (z->z0+) and for ``dir="-"`` the limit from the left (z->z0-). For infinite z0 + (oo or -oo), the dir argument does not matter. + + This algorithm is fully described in the module docstring in the gruntz.py + file. It relies heavily on the series expansion. Most frequently, gruntz() + is only used if the faster limit() function (which uses heuristics) fails. + """ + + if str(dir) == "-": + e0 = e.subs(z, z0 - 1/z) + elif str(dir) == "+": + e0 = e.subs(z, z0 + 1/z) + else: + raise NotImplementedError("dir must be '+' or '-'") + + r = limitinf(e0, z) + return r + +# tests +x = Symbol('x') +# Print the basic limit: +print(gruntz(sin(x)/x, x, 0)) + +# Test other cases +assert gruntz(sin(x)/x, x, 0) == 1 +assert gruntz(2*sin(x)/x, x, 0) == 2 +assert gruntz(sin(2*x)/x, x, 0) == 2 +assert gruntz(sin(x)**2/x, x, 0) == 0 +assert gruntz(sin(x)/x**2, x, 0) == oo +assert gruntz(sin(x)**2/x**2, x, 0) == 1 +assert gruntz(sin(sin(sin(x)))/sin(x), x, 0) == 1 +assert gruntz(2*log(x+1)/x, x, 0) == 2 +assert gruntz(sin((log(x+1)/x)*x)/x, x, 0) == 1 diff --git a/integration_tests/gruntz_demo3.py b/integration_tests/gruntz_demo3.py new file mode 100644 index 0000000000..a4fb48405c --- /dev/null +++ b/integration_tests/gruntz_demo3.py @@ -0,0 +1,264 @@ +from lpython import S +from sympy import Symbol, Pow, sin, oo, pi, E, Mul, Add, oo, log, exp, sign + +def mrv(e: S, x: S) -> list[S]: + """ + Calculate the MRV set of the expression. + + Examples + ======== + + >>> mrv(log(x - log(x))/log(x), x) + {x} + + """ + + if e.is_integer: + empty_list: list[S] = [] + return empty_list + if e == x: + list1: list[S] = [x] + return list1 + if e.func == log: + arg0: S = e.args[0] + list2: list[S] = mrv(arg0, x) + return list2 + if e.func == Mul or e.func == Add: + a: S = e.args[0] + b: S = e.args[1] + ans1: list[S] = mrv(a, x) + ans2: list[S] = mrv(b, x) + list3: list[S] = mrv_max(ans1, ans2, x) + return list3 + if e.func == Pow: + base: S = e.args[0] + list4: list[S] = mrv(base, x) + return list4 + if e.func == sin: + list5: list[S] = [x] + return list5 + # elif e.is_Function: + # return reduce(lambda a, b: mrv_max(a, b, x), (mrv(a, x) for a in e.args)) + raise NotImplementedError(f"Can't calculate the MRV of {e}.") + +def mrv_max(f: list[S], g: list[S], x: S) -> list[S]: + """Compute the maximum of two MRV sets. + + Examples + ======== + + >>> mrv_max({log(x)}, {x**5}, x) + {x**5} + + """ + + if len(f) == 0: + return g + elif len(g) == 0: + return f + # elif f & g: + # return f | g + else: + f1: S = f[0] + g1: S = g[0] + bool1: bool = f1 == x + bool2: bool = g1 == x + if bool1 and bool2: + l: list[S] = [x] + return l + +def rewrite(e: S, x: S, w: S) -> S: + """ + Rewrites the expression in terms of the MRV subexpression. + + Parameters + ========== + + e : Expr + an expression + x : Symbol + variable of the `e` + w : Symbol + The symbol which is going to be used for substitution in place + of the MRV in `x` subexpression. + + Returns + ======= + + The rewritten expression + + Examples + ======== + + >>> rewrite(exp(x)*log(x), x, y) + (log(x)/y, -x) + + """ + Omega: list[S] = mrv(e, x) + Omega1: S = Omega[0] + + if Omega1 == x: + newe: S = e.subs(x, S(1)/w) + return newe + +def signinf(e: S, x : S) -> S: + r""" + Determine sign of the expression at the infinity. + + Returns + ======= + + {1, 0, -1} + One or minus one, if `e > 0` or `e < 0` for `x` sufficiently + large and zero if `e` is *constantly* zero for `x\to\infty`. + + """ + + if not e.has(x): + return sign(e) + if e == x: + return S(1) + if e.func == Pow: + base: S = e.args[0] + if signinf(base, x) == S(1): + return S(1) + +def leadterm(e: S, x: S) -> list[S]: + """ + Returns the leading term a*x**b as a list [a, b]. + """ + + l1: list[S] = [S(1), S(0)] + l2: list[S] = [S(2), S(0)] + l3: list[S] = [S(1), S(1)] + l4: list[S] = [S(1), S(-1)] + + if e == sin(x)/x: + return l1 + elif e == S(2)*sin(x)/x: + return l2 + elif e == sin(S(2)*x)/x: + return l2 + elif e == sin(x)**S(2)/x: + return l3 + elif e == sin(x)/x**S(2): + return l4 + elif e == sin(x)**S(2)/x**S(2): + return l1 + elif e == sin(sin(sin(x)))/sin(x): + return l1 + elif e == S(2)*log(x+S(1))/x: + return l2 + elif e == sin((log(x+S(1))/x)*x)/x: + return l1 + raise NotImplementedError(f"Can't calculate the leadterm of {e}.") + +def mrv_leadterm(e: S, x: S) -> list[S]: + """ + Compute the leading term of the series. + + Returns + ======= + + tuple + The leading term `c_0 w^{e_0}` of the series of `e` in terms + of the most rapidly varying subexpression `w` in form of + the pair ``(c0, e0)`` of Expr. + + Examples + ======== + + >>> leadterm(1/exp(-x + exp(-x)) - exp(x), x) + (-1, 0) + + """ + # w = Dummy('w', real=True, positive=True) + # e = rewrite(e, x, w) + # return e.leadterm(w) + w: S = Symbol('w') + newe: S = rewrite(e, x, w) + coeff_exp_list: list[S] = leadterm(newe, w) + return coeff_exp_list + +def limitinf(e: S, x: S) -> S: + """ + Compute the limit of the expression at the infinity. + + Examples + ======== + + >>> limitinf(exp(x)*(exp(1/x - exp(-x)) - exp(1/x)), x) + -1 + + """ + if not e.has(x): + return e + + coeff_exp_list: list[S] = mrv_leadterm(e, x) + c0: S = coeff_exp_list[0] + e0: S = coeff_exp_list[1] + sig: S = signinf(e0, x) + case_2: S = signinf(c0, x) * oo + if sig == S(1): + return S(0) + if sig == S(-1): + return case_2 + if sig == S(0): + return limitinf(c0, x) + raise NotImplementedError(f'Result depends on the sign of {sig}.') + +def gruntz(e: S, z: S, z0: S, dir: str ="+") -> S: + """ + Compute the limit of e(z) at the point z0 using the Gruntz algorithm. + + Explanation + =========== + + ``z0`` can be any expression, including oo and -oo. + + For ``dir="+"`` (default) it calculates the limit from the right + (z->z0+) and for ``dir="-"`` the limit from the left (z->z0-). For infinite z0 + (oo or -oo), the dir argument does not matter. + + This algorithm is fully described in the module docstring in the gruntz.py + file. It relies heavily on the series expansion. Most frequently, gruntz() + is only used if the faster limit() function (which uses heuristics) fails. + """ + + e0: S + sub_neg: S = z0 - S(1)/z + sub_pos: S = z0 + S(1)/z + if str(dir) == "-": + e0 = e.subs(z, sub_neg) + elif str(dir) == "+": + e0 = e.subs(z, sub_pos) + else: + raise NotImplementedError("dir must be '+' or '-'") + + r: S = limitinf(e0, z) + return r + +# test +def test(): + x: S = Symbol('x') + print(gruntz(sin(x)/x, x, S(0), "+")) + print(gruntz(S(2)*sin(x)/x, x, S(0), "+")) + print(gruntz(sin(S(2)*x)/x, x, S(0), "+")) + print(gruntz(sin(x)**S(2)/x, x, S(0), "+")) + print(gruntz(sin(x)/x**S(2), x, S(0), "+")) + print(gruntz(sin(x)**S(2)/x**S(2), x, S(0), "+")) + print(gruntz(sin(sin(sin(x)))/sin(x), x, S(0), "+")) + print(gruntz(S(2)*log(x+S(1))/x, x, S(0), "+")) + print(gruntz(sin((log(x+S(1))/x)*x)/x, x, S(0), "+")) + + assert gruntz(sin(x)/x, x, S(0)) == S(1) + assert gruntz(S(2)*sin(x)/x, x, S(0)) == S(2) + assert gruntz(sin(S(2)*x)/x, x, S(0)) == S(2) + assert gruntz(sin(x)**S(2)/x, x, S(0)) == S(0) + assert gruntz(sin(x)/x**S(2), x, S(0)) == oo + assert gruntz(sin(x)**S(2)/x**S(2), x, S(0)) == S(1) + assert gruntz(sin(sin(sin(x)))/sin(x), x, S(0)) == S(1) + assert gruntz(S(2)*log(x+S(1))/x, x, S(0)) == S(2) + assert gruntz(sin((log(x+S(1))/x)*x)/x, x, S(0)) == S(1) + +test() \ No newline at end of file diff --git a/integration_tests/if_01.py b/integration_tests/if_01.py index 842cf15443..dccda55adb 100644 --- a/integration_tests/if_01.py +++ b/integration_tests/if_01.py @@ -1,3 +1,5 @@ +from lpython import i32 + def Test_if_01(): z: i32 = 0 if True: diff --git a/integration_tests/if_02.py b/integration_tests/if_02.py index e3a5b203b6..2a607f7ae3 100644 --- a/integration_tests/if_02.py +++ b/integration_tests/if_02.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_if_01(): x: bool = True diff --git a/integration_tests/if_03.py b/integration_tests/if_03.py new file mode 100644 index 0000000000..780a7a7af8 --- /dev/null +++ b/integration_tests/if_03.py @@ -0,0 +1,5 @@ +from sys import exit + +if True: + print("Yes, true") + exit(1) diff --git a/integration_tests/import_order_01.py b/integration_tests/import_order_01.py new file mode 100644 index 0000000000..0d8724338d --- /dev/null +++ b/integration_tests/import_order_01.py @@ -0,0 +1,7 @@ +from import_order_01b import f +from lpython import i32, ccallback + +@ccallback +def main1(): + a: i32 = f() + print(a) diff --git a/integration_tests/import_order_01b.py b/integration_tests/import_order_01b.py new file mode 100644 index 0000000000..2dd1989d2a --- /dev/null +++ b/integration_tests/import_order_01b.py @@ -0,0 +1,4 @@ +from lpython import i32 + +def f() -> i32: + return 42 diff --git a/integration_tests/intent_01.py b/integration_tests/intent_01.py new file mode 100644 index 0000000000..e4f679b05c --- /dev/null +++ b/integration_tests/intent_01.py @@ -0,0 +1,26 @@ +from lpython import i32, u32, f64, dataclass, In, Out, InOut + +@dataclass +class Foo: + p: i32 + +def f(x: i32, y: In[f64], z: InOut[list[u32]], w: Out[Foo]): + assert (x == -12) + assert abs(y - (4.44)) <= 1e-12 + z.append(u32(5)) + w.p = 24 + + +def main0(): + a: i32 = (-12) + b: f64 = 4.44 + c: list[u32] = [u32(1), u32(2), u32(3), u32(4)] + d: Foo = Foo(25) + + print(a, b, c, d.p) + + f(a, b, c, d) + assert c[-1] == u32(5) + assert d.p == 24 + +main0() diff --git a/integration_tests/intrinsics_01.py b/integration_tests/intrinsics_01.py new file mode 100644 index 0000000000..5547e86206 --- /dev/null +++ b/integration_tests/intrinsics_01.py @@ -0,0 +1,15 @@ +from numpy import array + +def any_01() -> None: + x: bool[2] + + x= array([False, False]) + assert not any(x) + + x = array([False, True]) + assert any(x) + + x = array([True, True]) + assert any(x) + +any_01() diff --git a/integration_tests/intrinsics_02.py b/integration_tests/intrinsics_02.py new file mode 100644 index 0000000000..c37d0aad3d --- /dev/null +++ b/integration_tests/intrinsics_02.py @@ -0,0 +1,42 @@ +from lpython import Const, i32, f32, f64 + +foo: Const[i32] = 4 +bar: Const[i32] = foo // 2 + +print(bar) +assert bar == 2 + +def floordiv1(): + a: f64 + b: f64 + c: f64 + a = 5.0 + b = 2.0 + c = a // b + + print(c) + assert c == 2.0 + +def floordiv2(): + a: Const[f32] = f32(5.0) + b: Const[f32] = f32(2.0) + c: f32 + c = a // b + + print(c) + assert c == f32(2.0) + +def floordiv3(): + a: f64 + b: f64 + c: f64 + a = 5.0 + b = -2.0 + c = a // b + + print(c) + assert c == -3.0 + +floordiv1() +floordiv2() +floordiv3() diff --git a/integration_tests/kwargs_01.py b/integration_tests/kwargs_01.py index 16fc30e5ea..2752769a15 100644 --- a/integration_tests/kwargs_01.py +++ b/integration_tests/kwargs_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, f32, f64, c64, overload +from lpython import i32, i64, f32, f64, c64, overload def func01(a: i32, b: i64) -> i64: return int(a) + b diff --git a/integration_tests/lambda_01.py b/integration_tests/lambda_01.py new file mode 100644 index 0000000000..7e49e4884c --- /dev/null +++ b/integration_tests/lambda_01.py @@ -0,0 +1,16 @@ +from lpython import i32, Callable + +def main0(): + x: Callable[[i32, i32, i32], i32] = lambda p, q, r: p + q + r + + a123: i32 = x(1, 2, 3) + a456: i32 = x(4, 5, 6) + a_1_2_3: i32 = x(-1, -2, -3) + + print(a123, a456, a_1_2_3) + + assert a123 == 6 + assert a456 == 15 + assert a_1_2_3 == -6 + +main0() diff --git a/integration_tests/list_01.py b/integration_tests/list_01.py new file mode 100644 index 0000000000..088b2237dd --- /dev/null +++ b/integration_tests/list_01.py @@ -0,0 +1,21 @@ +from lpython import i32 + +l: list[i32] = [1, 2, 3, 4] +print("Before Pop:", l) + +assert len(l) == 4 +assert l[0] == 1 +assert l[1] == 2 +assert l[2] == 3 +assert l[3] == 4 + +x: i32 = l.pop() +print("After Pop:", l) + +assert x == 4 +assert len(l) == 3 +assert l[0] == 1 +assert l[1] == 2 +assert l[2] == 3 + +print("Popped Element: ", x) diff --git a/src/libasr/compiler_tester/__init__.py b/integration_tests/lnn/__init__.py similarity index 100% rename from src/libasr/compiler_tester/__init__.py rename to integration_tests/lnn/__init__.py diff --git a/integration_tests/lnn/perceptron/__init__.py b/integration_tests/lnn/perceptron/__init__.py new file mode 100644 index 0000000000..1f60fac51f --- /dev/null +++ b/integration_tests/lnn/perceptron/__init__.py @@ -0,0 +1 @@ +from .perceptron_main import init_perceptron, train_dataset, test_perceptron, print_perceptron, Perceptron diff --git a/integration_tests/lnn/perceptron/perceptron_main.py b/integration_tests/lnn/perceptron/perceptron_main.py new file mode 100644 index 0000000000..a60fe8a4e8 --- /dev/null +++ b/integration_tests/lnn/perceptron/perceptron_main.py @@ -0,0 +1,96 @@ +from lpython import dataclass, i32, f64, InOut +from sys import exit + +@dataclass +class Perceptron: + no_of_inputs: i32 + weights: list[f64] + learn_rate: f64 + iterations_limit: i32 + des_accuracy: f64 + cur_accuracy: f64 + epochs_cnt: i32 + +def get_inp_vec_with_bias(a: list[f64]) -> list[f64]: + b: list[f64] = [] + i: i32 + for i in range(len(a)): + b.append(a[i]) + b.append(1.0) + return b + +def init_weights(size: i32) -> list[f64]: + weights: list[f64] = [] + i: i32 + for i in range(size): + weights.append(0.0) + weights.append(0.0) # append bias + return weights + +def init_perceptron(p: InOut[Perceptron], n: i32, rate: f64, iterations_limit: i32, des_accuracy: f64): + if (n < 1 or n > 1000): + print("no_of_inputs must be between [1, 1000]") + exit(1) + p.no_of_inputs = n + p.weights = init_weights(n) + p.learn_rate = rate + p.iterations_limit = iterations_limit + p.des_accuracy = des_accuracy + p.cur_accuracy = 0.0 + p.epochs_cnt = 0 + +def train_perceptron(p: InOut[Perceptron], input_vector: list[f64], actual_output: i32): + predicted_output: i32 = predict_perceptron(p, input_vector) + error: i32 = actual_output - predicted_output + i: i32 + for i in range(len(input_vector)): + p.weights[i] += p.learn_rate * f64(error) * f64(input_vector[i]) + +def predict_perceptron(p: Perceptron, input_vector: list[f64]) -> i32: + weighted_sum: f64 = 0.0 + i: i32 = 0 + for i in range(len(input_vector)): + weighted_sum = weighted_sum + p.weights[i] * f64(input_vector[i]) + return activation_function(weighted_sum) + +def activation_function(value: f64) -> i32: + if value >= 0.0: + return 1 + return -1 + +def train_epoch(p: Perceptron, input_vectors: list[list[f64]], outputs: list[i32]): + i: i32 + for i in range(len(input_vectors)): + input_vector: list[f64] = get_inp_vec_with_bias(input_vectors[i]) + if predict_perceptron(p, input_vector) != outputs[i]: + train_perceptron(p, input_vector, outputs[i]) + +def train_dataset(p: InOut[Perceptron], input_vectors: list[list[f64]], outputs: list[i32]): + p.cur_accuracy = 0.0 + p.epochs_cnt = 0 + while p.cur_accuracy < p.des_accuracy and p.epochs_cnt < p.iterations_limit: + p.epochs_cnt += 1 + train_epoch(p, input_vectors, outputs) + p.cur_accuracy = test_perceptron(p, input_vectors, outputs) + +def test_perceptron(p: Perceptron, input_vectors: list[list[f64]], outputs: list[i32]) -> f64: + correctly_classified_cnt: i32 = 0 + i: i32 + for i in range(len(input_vectors)): + input_vector: list[f64] = get_inp_vec_with_bias(input_vectors[i]) + if predict_perceptron(p, input_vector) == outputs[i]: + correctly_classified_cnt += 1 + return (correctly_classified_cnt / len(input_vectors)) * 100.0 + +def print_perceptron(p: Perceptron): + print("weights = [", end = "") + i: i32 + for i in range(p.no_of_inputs): + print(p.weights[i], end = ", ") + print(p.weights[p.no_of_inputs], end = "(bias)]\n") + print("learn_rate = ", end = "") + print(p.learn_rate) + print("accuracy = ", end = "") + print(p.cur_accuracy) + print("epochs_cnt = ", end = "") + print(p.epochs_cnt) diff --git a/integration_tests/lnn/regression/__init__.py b/integration_tests/lnn/regression/__init__.py new file mode 100644 index 0000000000..de58667620 --- /dev/null +++ b/integration_tests/lnn/regression/__init__.py @@ -0,0 +1 @@ +from .regression_main import init_perceptron, train_dataset, test_perceptron, print_perceptron, Perceptron diff --git a/integration_tests/lnn/regression/regression_main.py b/integration_tests/lnn/regression/regression_main.py new file mode 100644 index 0000000000..f5ad9979f7 --- /dev/null +++ b/integration_tests/lnn/regression/regression_main.py @@ -0,0 +1,92 @@ +from lpython import dataclass, i32, f64, InOut +from sys import exit + +@dataclass +class Perceptron: + no_of_inputs: i32 + weights: list[f64] + learn_rate: f64 + iterations_limit: i32 + err_limit: f64 + err: f64 + epochs_cnt: i32 + +def get_inp_vec_with_bias(a: list[f64]) -> list[f64]: + b: list[f64] = [] + i: i32 + for i in range(len(a)): + b.append(a[i]) + b.append(1.0) + return b + +def init_weights(size: i32) -> list[f64]: + weights: list[f64] = [] + i: i32 + for i in range(size): + weights.append(0.0) + weights.append(0.0) # append bias + return weights + +def init_perceptron(p: InOut[Perceptron], n: i32, rate: f64, iterations_limit: i32, err_limit: f64): + p.no_of_inputs = n + p.weights = init_weights(n) + p.learn_rate = rate + p.iterations_limit = iterations_limit + p.err_limit = err_limit + p.err = 1.0 + p.epochs_cnt = 0 + +def train_perceptron(p: InOut[Perceptron], input_vector: list[f64], actual_output: f64): + predicted_output: f64 = predict_perceptron(p, input_vector) + error: f64 = actual_output - predicted_output + i: i32 + for i in range(len(input_vector)): + p.weights[i] += p.learn_rate * f64(error) * f64(input_vector[i]) + +def predict_perceptron(p: Perceptron, input_vector: list[f64]) -> f64: + weighted_sum: f64 = 0.0 + i: i32 = 0 + for i in range(len(input_vector)): + weighted_sum = weighted_sum + p.weights[i] * f64(input_vector[i]) + return activation_function(weighted_sum) + +def activation_function(value: f64) -> f64: + return value + +def train_epoch(p: Perceptron, input_vectors: list[list[f64]], outputs: list[f64]): + i: i32 + for i in range(len(input_vectors)): + input_vector: list[f64] = get_inp_vec_with_bias(input_vectors[i]) + if predict_perceptron(p, input_vector) != outputs[i]: + train_perceptron(p, input_vector, outputs[i]) + +def train_dataset(p: InOut[Perceptron], input_vectors: list[list[f64]], outputs: list[f64]): + prev_err: f64 = 0.0 + p.err = 1.0 + p.epochs_cnt = 0 + while abs(p.err - prev_err) >= p.err_limit and p.epochs_cnt < p.iterations_limit: + p.epochs_cnt += 1 + train_epoch(p, input_vectors, outputs) + prev_err = p.err + p.err = test_perceptron(p, input_vectors, outputs) + +def test_perceptron(p: Perceptron, input_vectors: list[list[f64]], outputs: list[f64]) -> f64: + err: f64 = 0.0 + i: i32 + for i in range(len(input_vectors)): + input_vector: list[f64] = get_inp_vec_with_bias(input_vectors[i]) + err = err + (outputs[i] - predict_perceptron(p, input_vector)) ** 2.0 + return err + +def print_perceptron(p: Perceptron): + print("weights = [", end = "") + i: i32 + for i in range(p.no_of_inputs): + print(p.weights[i], end = ", ") + print(p.weights[p.no_of_inputs], end = "(bias)]\n") + print("learn_rate = ", end = "") + print(p.learn_rate) + print("error = ", end = "") + print(p.err) + print("epochs_cnt = ", end = "") + print(p.epochs_cnt) diff --git a/integration_tests/lnn/utils/__init__.py b/integration_tests/lnn/utils/__init__.py new file mode 100644 index 0000000000..26df89840f --- /dev/null +++ b/integration_tests/lnn/utils/__init__.py @@ -0,0 +1 @@ +from .utils_main import normalize, normalize_input_vectors, normalize_output_vector diff --git a/integration_tests/lnn/utils/utils_main.py b/integration_tests/lnn/utils/utils_main.py new file mode 100644 index 0000000000..4ee4f32f66 --- /dev/null +++ b/integration_tests/lnn/utils/utils_main.py @@ -0,0 +1,44 @@ +from lpython import i32, f64, InOut + +def normalize(value: f64, leftMin: f64, leftMax: f64, rightMin: f64, rightMax: f64) -> f64: + # Figure out how 'wide' each range is + leftSpan: f64 = leftMax - leftMin + rightSpan: f64 = rightMax - rightMin + + # Convert the left range into a 0-1 range (float) + valueScaled: f64 = (value - leftMin) / leftSpan + + # Convert the 0-1 range into a value in the right range. + return rightMin + (valueScaled * rightSpan) + +def normalize_input_vectors(input_vectors: InOut[list[list[f64]]]): + rows: i32 = len(input_vectors) + cols: i32 = len(input_vectors[0]) + + j: i32 + for j in range(cols): + colMinVal: f64 = input_vectors[0][j] + colMaxVal: f64 = input_vectors[0][j] + i: i32 + for i in range(rows): + if input_vectors[i][j] > colMaxVal: + colMaxVal = input_vectors[i][j] + if input_vectors[i][j] < colMinVal: + colMinVal = input_vectors[i][j] + + for i in range(rows): + input_vectors[i][j] = normalize(input_vectors[i][j], colMinVal, colMaxVal, -1.0, 1.0) + +def normalize_output_vector(output_vector: InOut[list[f64]]): + rows: i32 = len(output_vector) + colMinVal: f64 = output_vector[0] + colMaxVal: f64 = output_vector[0] + i: i32 + for i in range(rows): + if output_vector[i] > colMaxVal: + colMaxVal = output_vector[i] + if output_vector[i] < colMinVal: + colMinVal = output_vector[i] + + for i in range(rows): + output_vector[i] = normalize(output_vector[i], colMinVal, colMaxVal, -1.0, 1.0) diff --git a/integration_tests/logical_binop1.py b/integration_tests/logical_binop1.py index e7fe3a43e5..4c610e0236 100644 --- a/integration_tests/logical_binop1.py +++ b/integration_tests/logical_binop1.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_issue_1487_1(): # OR operator: a or b a : i32 diff --git a/integration_tests/loop_01.py b/integration_tests/loop_01.py index 1b4f54a3c9..306dc9a09b 100644 --- a/integration_tests/loop_01.py +++ b/integration_tests/loop_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, i16 +from lpython import i32, i64, i16 def main0(): s: str = 'aabbcc'; c: str diff --git a/integration_tests/loop_02.py b/integration_tests/loop_02.py index bfd7eca86c..447ef6e6ad 100644 --- a/integration_tests/loop_02.py +++ b/integration_tests/loop_02.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_loop_01(): i: i32 = 0 j: i32 = 0 diff --git a/integration_tests/loop_03.py b/integration_tests/loop_03.py index 9101f0889c..dca553b2ba 100644 --- a/integration_tests/loop_03.py +++ b/integration_tests/loop_03.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_loop_01(): i: i32 = 0 diff --git a/integration_tests/loop_04.py b/integration_tests/loop_04.py index a219db9378..1374a4edc8 100644 --- a/integration_tests/loop_04.py +++ b/integration_tests/loop_04.py @@ -1,6 +1,8 @@ -from ltypes import i32 +from lpython import i32 + j: i32 i: i32 + for i in range(5): j = i - print("j: ", j) \ No newline at end of file + print("j: ", j) diff --git a/integration_tests/loop_05.py b/integration_tests/loop_05.py new file mode 100644 index 0000000000..fe06d74acd --- /dev/null +++ b/integration_tests/loop_05.py @@ -0,0 +1,13 @@ +from lpython import i32 + +def f(): + j: i32 = 0 + while True: + j = j + 1 + print(j) + if j > 4: + break + print("out of outer loop") + assert j == 5 + +f() diff --git a/integration_tests/loop_06.py b/integration_tests/loop_06.py new file mode 100644 index 0000000000..4b1bdfc120 --- /dev/null +++ b/integration_tests/loop_06.py @@ -0,0 +1,23 @@ +from lpython import i32 +from sys import exit + +def test_for(): + i: i32 + j: i32; k: i32; + k = 0 + for i in range(0, 10): + if i == 0: + j = 0 + continue + if i > 5: + k = k + i + break + if i == 3: + print(j, k) + assert j == 0 + assert k == 0 + quit() + print(j, k) + exit(2) + +test_for() diff --git a/integration_tests/loop_07.py b/integration_tests/loop_07.py new file mode 100644 index 0000000000..c0b045d5bb --- /dev/null +++ b/integration_tests/loop_07.py @@ -0,0 +1,17 @@ +from lpython import i32 + +def main0(): + points: list[tuple[i32, i32]] = [(445, 193), (138, 28), (418, 279)] + point: tuple[i32, i32] + x_sum: i32 = 0 + y_sum: i32 = 0 + for point in points: + print(point) + x_sum += point[0] + y_sum += point[1] + + print(x_sum, y_sum) + assert x_sum == 1001 + assert y_sum == 500 + +main0() diff --git a/integration_tests/loop_08.py b/integration_tests/loop_08.py new file mode 100644 index 0000000000..98ecbe2f7d --- /dev/null +++ b/integration_tests/loop_08.py @@ -0,0 +1,13 @@ +from lpython import i32, Const + +def main0(): + i: i32 + n: Const[i32] = 10 + M2: Const[i32] = 2 + y: i32 = 0 + for i in range(0, n, M2): # each M2 block in A cols and B rows # !!!!!!!!!!!!!! + y = y + 2 + print(y) + assert(y == 10) + +main0() diff --git a/integration_tests/loop_09.py b/integration_tests/loop_09.py new file mode 100644 index 0000000000..fabe12b747 --- /dev/null +++ b/integration_tests/loop_09.py @@ -0,0 +1,45 @@ +def with_break_for(): + i: i32 + s: i32 = 0 + for i in range(4): + s += i + break + else: + s += 10 + assert s == 0 + +def with_break_while(): + i: i32 = 0 + s: i32 = 0 + while i < 4: + s += i + break + else: + s += 10 + assert s == 0 + +def no_break_for(): + i: i32 + s: i32 = 0 + for i in range(2): + s += i + else: + s += 10 + assert s == 11 + +def no_break_while(): + i: i32 = 0 + s: i32 = 0 + while i < 2: + s += i + i += 1 + else: + s += 10 + assert s == 11 + +no_break_for() +no_break_while() + +with_break_for() +with_break_while() + diff --git a/integration_tests/loop_10.py b/integration_tests/loop_10.py new file mode 100644 index 0000000000..6f9f0defb9 --- /dev/null +++ b/integration_tests/loop_10.py @@ -0,0 +1,126 @@ +def with_break_for(): + i: i32 = 0 + for i in range(4): + i += 1 + break + else: + assert False + + +def with_break_while(): + i: i32 = 0 + while i < 4: + i += 1 + break + else: + assert False + + +def no_break_for(): + i: i32 + j: i32 = 0 + for i in range(2): + j += 1 + else: + print(j) + assert j == 2 + return + assert False + +def break_in_if_for(): + i: i32 + j: i32 = 0 + for i in range(2): + j += 1 + if i == 1: + break + else: + assert False + print(j) + assert j == 2 + +def nested_loop_for_for(): + i: i32 + j: i32 + m: i32 = 0 + for i in range(2): + for j in range(10, 20): + break + else: + m = 10 + print(m) + assert m == 10 + +def nested_loop_for_while(): + i: i32 + j: i32 = 10 + m: i32 = 0 + for i in range(2): + while j < 20: + break + else: + m = 10 + print(m) + assert m == 10 + +def nested_loop_while_for(): + i: i32 = 0 + j: i32 + m: i32 = 0 + while i < 2: + i += 1 + for j in range(10, 20): + break + else: + print(i) + assert i == 2 + m = 10 + print(m) + assert m == 10 + +def nested_loop_while_while(): + i: i32 = 0 + j: i32 = 10 + m: i32 = 0 + while i < 2: + i += 1 + while j < 20: + break + else: + print(i) + assert i == 2 + m = 10 + print(m) + assert m == 10 + +def nested_loop_else(): + i: i32 + j: i32 + l: i32 = 0 + m: i32 = 0 + for i in range(2): + l += 1 + m: i32 = 0 + for j in range(10, 12): + m += 1 + else: + print(m) + assert m == 2 + l += 10 + else: + print(l) + assert l == 22 + m = 10 + print(m) + assert m == 10 + + +with_break_for() +with_break_while() +no_break_for() +break_in_if_for() +nested_loop_for_for() +nested_loop_for_while() +nested_loop_while_for() +nested_loop_while_while() +nested_loop_else() diff --git a/integration_tests/loop_11.py b/integration_tests/loop_11.py new file mode 100644 index 0000000000..c5db7a40a9 --- /dev/null +++ b/integration_tests/loop_11.py @@ -0,0 +1,42 @@ +from lpython import i32 + +#checking for loops in the global scope +sum: i32 = 0 +i: i32 +for i in [1, 2, 3, 4]: + print(i) + sum += i +print("sum = ",sum) +assert sum == 10 + +alphabets: str = "" +c: str +for c in "abcde": + print(c) + alphabets += c +print("alphabets = ",alphabets) +assert alphabets == "abcde" + +alphabets = "" +s : str = "abcde" +for c in s[1:4]: + print(c) + alphabets += c +print("alphabets = ",alphabets) +assert alphabets == "bcd" + +sum = 0 +num_list : list[i32] = [1, 2, 3, 4] +for i in num_list[1:3]: + print(i) + sum += i +print("sum = ",sum) +assert sum == 5 + +sum = 0 +nested_list : list[list[i32]] = [[1, 2, 3, 4]] +for i in nested_list[0]: + print(i) + sum += i +print("sum = ",sum) +assert sum == 10 \ No newline at end of file diff --git a/integration_tests/loop_12.py b/integration_tests/loop_12.py new file mode 100644 index 0000000000..fb12c26981 --- /dev/null +++ b/integration_tests/loop_12.py @@ -0,0 +1,67 @@ + +def test_for_dict_int(): + dict_int: dict[i32, i32] = {1:2, 2:3, 3:4} + key: i32 + s1: i32 = 0 + s2: i32 = 0 + + for key in dict_int: + print(key) + s1 += key + s2 += dict_int[key] + + assert s1 == 6 + assert s2 == 9 + +def test_for_dict_str(): + dict_str: dict[str, str] = {"a":"b", "c":"d"} + key: str + s1: str = "" + s2: str = "" + + for key in dict_str: + print(key) + s1 += key + s2 += dict_str[key] + + assert (s1 == "ac" or s1 == "ca") + assert ((s1 == "ac" and s2 == "bd") or (s1 == "ca" and s2 == "db")) + +def test_for_set_int(): + set_int: set[i32] = {1, 2, 3} + el: i32 + s: i32 = 0 + + for el in set_int: + print(el) + s += el + + assert s == 6 + +def test_for_set_str(): + set_str: set[str] = {'a', 'b'} + el: str + s: str = "" + + for el in set_str: + print(el) + s += el + + assert (s == "ab" or s == "ba") + +def test_nested(): + graph: dict[i32, set[i32]] = {1: {2, 3}} + el: i32 + s: i32 = 0 + for el in graph[1]: + print(el) + s += el + + assert s == 5 + + +test_for_dict_int() +test_for_set_int() +test_for_dict_str() +test_for_set_str() +test_nested() diff --git a/integration_tests/lpconvexhull/__init__.py b/integration_tests/lpconvexhull/__init__.py new file mode 100644 index 0000000000..7744538843 --- /dev/null +++ b/integration_tests/lpconvexhull/__init__.py @@ -0,0 +1 @@ +from .lpconvexhull_main import convex_hull diff --git a/integration_tests/lpconvexhull/lpconvexhull_main.py b/integration_tests/lpconvexhull/lpconvexhull_main.py new file mode 100644 index 0000000000..7bdfa62af2 --- /dev/null +++ b/integration_tests/lpconvexhull/lpconvexhull_main.py @@ -0,0 +1,56 @@ +from lpython import i32 +from .utils import min, distance + +def orientation(p: tuple[i32, i32], q: tuple[i32, i32], r: tuple[i32, i32]) -> i32: + # Function to find the orientation of triplet (p, q, r) + # Returns the following values: + # 0: Colinear + # 1: Clockwise + # 2: Counterclockwise + value: i32 = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]) + if value == 0: + return 0 # Colinear + elif value > 0: + return 1 # Clockwise + else: + return 2 # Counterclockwise + + +def convex_hull(points: list[tuple[i32, i32]]) -> list[tuple[i32, i32]]: + """Finds the convex hull of a set of points. + + Args: + points: A list of points. + + Returns: + A list of points that form the convex hull. + """ + + n: i32 = len(points) + if n < 3: + return [(-1, -1)] # Convex hull not possible + + # Find the leftmost point + leftmost: tuple[i32, i32] = min(points) + hull: list[tuple[i32, i32]] = [] + + p: tuple[i32, i32] = leftmost + + while True: + hull.append(p) + q: tuple[i32, i32] = points[0] + + r: tuple[i32, i32] + for r in points: + if r == p or r == q: + continue + direction: i32 = orientation(p, q, r) + if direction == 1 or (direction == 0 and distance(p, r) > distance(p, q)): + q = r + + p = q + + if p == leftmost: + break + + return hull diff --git a/integration_tests/lpconvexhull/utils.py b/integration_tests/lpconvexhull/utils.py new file mode 100644 index 0000000000..a414cb7fa7 --- /dev/null +++ b/integration_tests/lpconvexhull/utils.py @@ -0,0 +1,29 @@ +from lpython import i32, f64 + +def min(points: list[tuple[i32, i32]]) -> tuple[i32, i32]: + """Finds the left-most point in a list of points. + + Args: + points: A list of points. + + Returns: + The left-most point in the list. + """ + + left_most_point: tuple[i32, i32] = points[0] + point: tuple[i32, i32] + for point in points: + if point[0] < left_most_point[0]: + left_most_point = point + + return left_most_point + + +def distance(p: tuple[i32, i32], q: tuple[i32, i32]) -> f64: + # Function to calculate the Euclidean distance between two points + x1: i32; y1: i32 + x2: i32; y2: i32 + + x1, y1 = p + x2, y2 = q + return f64((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 diff --git a/integration_tests/lpdraw/__init__.py b/integration_tests/lpdraw/__init__.py new file mode 100644 index 0000000000..699214668a --- /dev/null +++ b/integration_tests/lpdraw/__init__.py @@ -0,0 +1 @@ +from .draw import Pixel, Line, Circle, Display, DisplayTerminal, Clear diff --git a/integration_tests/lpdraw/draw.py b/integration_tests/lpdraw/draw.py new file mode 100644 index 0000000000..771d9ea7a9 --- /dev/null +++ b/integration_tests/lpdraw/draw.py @@ -0,0 +1,108 @@ +from lpython import i32, f64, TypeVar +import numpy + +H = TypeVar("H") +W = TypeVar("W") + +def Pixel(H: i32, W: i32, Screen: i32[H, W], x: i32, y: i32) -> None: + if x >= 0 and y >= 0 and x < W and y < H: + Screen[H - 1 - y, x] = 255 + +def Clear(H: i32, W: i32, Screen: i32[H, W]): + i: i32 + j: i32 + for i in range(H): + for j in range(W): + Screen[i, j] = 0 + +def DisplayTerminal(H: i32, W: i32, Screen: i32[H, W]): + i: i32 + j: i32 + + print("+", end = "") + for i in range(W): + print("-", end = "") + print("+") + + for i in range(H): + print("|", end = "") + for j in range(W): + if bool(Screen[i, j]): + print(".", end = "") + else: + print(" ", end = "") + print("|") + + print("+", end = "") + for i in range(W): + print("-", end = "") + print("+") + +def Display(H: i32, W: i32, Screen: i32[H, W]): + i: i32 + j: i32 + + print("P2") + print(W, H) + print(255) + + for i in range(H): + for j in range(W): + print(Screen[i, j]) + +def Line(H: i32, W: i32, Screen: i32[H, W], x1: i32, y1: i32, x2: i32, y2: i32) -> None: + dx: i32 = abs(x2 - x1) + dy: i32 = abs(y2 - y1) + + sx: i32 + sy: i32 + + if x1 < x2: + sx = 1 + else: + sx = -1 + + if y1 < y2: + sy = 1 + else: + sy = -1 + + err: i32 = dx - dy + + while x1 != x2 or y1 != y2: + Pixel(H, W, Screen, x1, y1) + e2: i32 = 2 * err + + if e2 > -dy: + err -= dy + x1 += sx + + if x1 == x2 and y1 == y2: + Pixel(H, W, Screen, x1, y1) + break + + if e2 < dx: + err += dx + y1 += sy + +def Circle(H: i32, W: i32, Screen: i32[H, W], x: i32, y: i32, r: f64) -> None: + x0: i32 = i32(r) + y0: i32 = 0 + err: i32 = 0 + + while x0 >= y0: + Pixel(H, W, Screen, x + x0, y + y0) + Pixel(H, W, Screen, x - x0, y + y0) + Pixel(H, W, Screen, x + x0, y - y0) + Pixel(H, W, Screen, x - x0, y - y0) + Pixel(H, W, Screen, x + y0, y + x0) + Pixel(H, W, Screen, x - y0, y + x0) + Pixel(H, W, Screen, x + y0, y - x0) + Pixel(H, W, Screen, x - y0, y - x0) + + if err <= 0: + y0 += 1 + err += 2 * y0 + 1 + if err > 0: + x0 -= 1 + err -= 2 * x0 + 1 diff --git a/integration_tests/lpython_decorator_01.py b/integration_tests/lpython_decorator_01.py new file mode 100644 index 0000000000..65b1082c86 --- /dev/null +++ b/integration_tests/lpython_decorator_01.py @@ -0,0 +1,16 @@ +from numpy import array +from lpython import i32, f64, lpython + +@lpython(backend="c", backend_optimisation_flags=["-ffast-math", "-funroll-loops", "-O3"]) +def fast_sum(n: i32, x: f64[:]) -> f64: + s: f64 = 0.0 + i: i32 + for i in range(n): + s += x[i] + return s + +def test(): + x: f64[3] = array([1.0, 2.0, 3.0]) + assert fast_sum(3, x) == 6.0 + +test() diff --git a/integration_tests/lpython_decorator_02.py b/integration_tests/lpython_decorator_02.py new file mode 100644 index 0000000000..31cb14c6ba --- /dev/null +++ b/integration_tests/lpython_decorator_02.py @@ -0,0 +1,39 @@ +from numpy import array +from lpython import i32, i64, f64, lpython, TypeVar, Const + +n = TypeVar("n") + +@lpython(backend="c", backend_optimisation_flags=["-ffast-math", "-funroll-loops"]) +def multiply_01(n: i32, x: f64[:]) -> f64[n]: + i: i32 + for i in range(n): + x[i] *= 5.0 + return x + +@lpython +def multiply_02(n: i32, x: i64[:], y: i64[:]) -> i64[n]: + z: i64[n]; i: i32 + for i in range(n): + z[i] = x[i] * y[i] + return z + +@lpython +def const_arg_sum(x: Const[i32]) -> i32: + return 10 + x + + +def test_01(): + size = 5 + x = array([11.0, 12.0, 13.0, 14.0, 15.0]) + y = multiply_01(size, x) + assert y[2] == 65. + + size = 3 + x = array([11, 12, 13]) + y = array([14, 15, 16]) + z = multiply_02(size, x, y) + for i in range(size): + assert z[i] == x[i] * y[i] + assert const_arg_sum(size) == size + 10 + +test_01() diff --git a/integration_tests/lpython_emulation_01.py b/integration_tests/lpython_emulation_01.py new file mode 100644 index 0000000000..29b6c4a6e5 --- /dev/null +++ b/integration_tests/lpython_emulation_01.py @@ -0,0 +1,21 @@ +import lpython_emulation_01_mod +import lpython +from lpython import ccall, i64 +from types import FunctionType +lpython.CTypes.emulations = {k: v for k, v in \ + lpython_emulation_01_mod.__dict__.items() \ + if isinstance(v, FunctionType)} + +@ccall +def f1(a: i64) -> i64: + pass + +@ccall +def f2(a: i64): + pass + +def main(): + assert f1(2) == 3 + f2(4) + +main() diff --git a/integration_tests/lpython_emulation_01_mod.py b/integration_tests/lpython_emulation_01_mod.py new file mode 100644 index 0000000000..3a12ea4c5d --- /dev/null +++ b/integration_tests/lpython_emulation_01_mod.py @@ -0,0 +1,7 @@ +from lpython import i64 + +def f1(a: i64) -> i64: + return a + 1 + +def f2(a: i64): + assert a == 4 diff --git a/integration_tests/modules_01.py b/integration_tests/modules_01.py index 5b70e2d23c..96a0cfb10e 100644 --- a/integration_tests/modules_01.py +++ b/integration_tests/modules_01.py @@ -1,4 +1,5 @@ from modules_01b import f #, g +from lpython import i32 def main0(): x: i32 diff --git a/integration_tests/modules_02.py b/integration_tests/modules_02.py index 690070701e..ccafc3e905 100644 --- a/integration_tests/modules_02.py +++ b/integration_tests/modules_02.py @@ -1,4 +1,5 @@ from modules_02b import f +from lpython import i32 def main0(): x: i32 diff --git a/integration_tests/nrp/__init__.py b/integration_tests/nrp/__init__.py new file mode 100644 index 0000000000..f5631d2af1 --- /dev/null +++ b/integration_tests/nrp/__init__.py @@ -0,0 +1 @@ +from .nr import newton_raphson diff --git a/integration_tests/nrp/nr.py b/integration_tests/nrp/nr.py new file mode 100644 index 0000000000..37c33a6905 --- /dev/null +++ b/integration_tests/nrp/nr.py @@ -0,0 +1,20 @@ +from lpython import i32, f64 + + +def func(x: f64, c: f64) -> f64: + return x**2.0 - c**2.0 + + +def func_prime(x: f64) -> f64: + return 2.0*x + + +def newton_raphson(x: f64, c: f64, maxiter: i32) -> f64: + h: f64 + err: f64 = 1e-5 + i: i32 = 0 + while abs(func(x, c)) > err and i < maxiter: + h = func(x, c) / func_prime(x) + x -= h + i += 1 + return x diff --git a/integration_tests/overload_testing.py b/integration_tests/overload_testing.py index 5fa06f88f0..d7cf1cd96c 100644 --- a/integration_tests/overload_testing.py +++ b/integration_tests/overload_testing.py @@ -1,4 +1,4 @@ -from ltypes import i32, overload +from lpython import i32, overload @overload def foo(a: i32, b: i32) -> i32: diff --git a/integration_tests/overload_testing2.py b/integration_tests/overload_testing2.py index 84ed4d0a4c..c01ae9f6a9 100644 --- a/integration_tests/overload_testing2.py +++ b/integration_tests/overload_testing2.py @@ -1,4 +1,4 @@ -from ltypes import i32, overload +from lpython import i32, overload @overload def foo2(a: i32, b: i32) -> i32: diff --git a/integration_tests/print_02.py b/integration_tests/print_02.py index d87009c59c..5b53eac8f8 100644 --- a/integration_tests/print_02.py +++ b/integration_tests/print_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 # Test: Printing ListConstant def f(): diff --git a/integration_tests/print_04.py b/integration_tests/print_04.py index b6a7cc4766..b66175cefc 100644 --- a/integration_tests/print_04.py +++ b/integration_tests/print_04.py @@ -1,4 +1,4 @@ -from ltypes import i8, i16, i32, i64 +from lpython import i8, i16, i32, i64 u: i64 = i64(-922337203685477580) print(u) diff --git a/integration_tests/print_06.py b/integration_tests/print_06.py new file mode 100644 index 0000000000..e3f05cf7f8 --- /dev/null +++ b/integration_tests/print_06.py @@ -0,0 +1,26 @@ +def main0(): + a: i32 = 1 + b: str = "abc" + c: list[i32] = [1, 2] + d: list[i32] = [3, 4] + e: tuple[i32, i32, i32] = (1, 2, 3) + f: tuple[i32, i32] = (4, 5) + print(a, b, c) + print(a, c, b) + print(c, a, b) + print(a, b, c, sep = "pqr") + print(a, c, b, sep = "pqr") + print(c, a, b, sep = "pqr") + print(a, b, c, end = "xyz\n") + print(a, c, b, end = "xyz\n") + print(c, a, b, end = "xyz\n") + print(a, b, c, sep = "pqr", end = "xyz\n") + print(a, c, b, sep = "pqr", end = "xyz\n") + print(c, a, b, sep = "pqr", end = "xyz\n") + # Tring out few cases with Lists and Tuples together + print(c, e) + print(c, d, a, sep = "pqr") + print(c, e, d, end = "xyz\n") + print(c, e, d, f, sep = "pqr", end = "xyz\n") + +main0() \ No newline at end of file diff --git a/integration_tests/print_float.py b/integration_tests/print_float.py index bd43c93b99..66ccb3878b 100644 --- a/integration_tests/print_float.py +++ b/integration_tests/print_float.py @@ -1,4 +1,4 @@ -from ltypes import f64 +from lpython import f64 def main0(): x: f64 = 0.00012 diff --git a/integration_tests/print_list_tuple.py b/integration_tests/print_list_tuple.py deleted file mode 100644 index c78bacd994..0000000000 --- a/integration_tests/print_list_tuple.py +++ /dev/null @@ -1,23 +0,0 @@ -from ltypes import f64, i32, c64 - - -def test_print_list(): - a: list[str] = ["ab", "abc", "abcd"] - b: list[i32] = [1, 2, 3, 4] - c: list[f64] = [1.23 , 324.3 , 56.431, 90.5, 34.1] - d: list[i32] = [] - - print(a, b) - print(c) - print(d) - - x: tuple[i32, str, i32] = (12, 'lpython', 32) - y: tuple[i32, str, str, i32] = (1, 'test', 'tuple', 3) - z: tuple[f64, f64, i32, bool] = (4.3, 6.45, 8, True) - t: tuple[i32, f64, str, c64] - t = (500, 240.02, 'complex-test', complex(42.0, 1.0)) - - print(x, y, z, t) - - -test_print_list() diff --git a/integration_tests/print_list_tuple_01.py b/integration_tests/print_list_tuple_01.py new file mode 100644 index 0000000000..2c599d9c0a --- /dev/null +++ b/integration_tests/print_list_tuple_01.py @@ -0,0 +1,36 @@ +from lpython import f64, i32, c64, InOut + + +def test_print_list(): + a: list[str] = ["ab", "abc", "abcd"] + b: list[i32] = [1, 2, 3, 4] + c: list[f64] = [1.23 , 324.3 , 56.431, 90.5, 34.1] + d: list[i32] = [] + + print(a, b) + print(c) + print(d) + + x: tuple[i32, str, i32] = (12, 'lpython', 32) + y: tuple[i32, str, str, i32] = (1, 'test', 'tuple', 3) + z: tuple[f64, f64, i32, bool] = (4.3, 6.45, 8, True) + t: tuple[i32, f64, str, c64] + t = (500, 240.02, 'complex-test', complex(42.0, 1.0)) + + print(x, y, z, t) + + +def f(y: InOut[list[i32]]) -> list[i32]: + y.append(4) + return y + +def g(): + print(f([1,2,3])) + + +def check(): + g() + test_print_list() + + +check() diff --git a/integration_tests/print_list_tuple_02.py b/integration_tests/print_list_tuple_02.py new file mode 100644 index 0000000000..57666c50e5 --- /dev/null +++ b/integration_tests/print_list_tuple_02.py @@ -0,0 +1,63 @@ +from lpython import i32, f64, InOut + +def insert_tuples_into_list(l: InOut[list[tuple[i32, f64, str]]], size: i32) -> list[tuple[i32, f64, str]]: + i: i32 + string: str + t: tuple[i32, f64, str] + + for i in range(size//2, size): + string = str(i) + "_str" + t = (i, float(i), string) + l.insert(i, t) + + return l + +def fill_list_of_tuples(size: i32) -> list[tuple[i32, f64, str]]: + l1: list[tuple[i32, f64, str]] = [] + t: tuple[i32, f64, str] + i: i32 + + for i in range(size): + t = (i, float(i), str(i) + "_str") + l1.append(t) + + return l1 + +def test_print_list_of_tuples(): + l1: list[tuple[i32, f64, str]] = [] + t: tuple[i32, f64, str] + size: i32 = 20 + i: i32 + string: str + + l1 = fill_list_of_tuples(size) + + print(l1) + + for i in range(size//2): + l1.remove(l1[len(l1) - 1]) + + t = l1[len(l1) - 1] + assert t[0] == size//2 - 1 + assert (t[1] - f64(size//2 - 1)) < 1e-10 + assert t[2] == str(size//2 - 1) + "_str" + + l1 = insert_tuples_into_list(l1, size) + + print(l1) + + for i in range(size): + string = str(-i) + "_str" + t = (-i, float(-i), string) + l1[i] = t + + print(l1) + +def test_print_tuple(): + x: tuple[i32, str] = (3, "hiyo") + y: tuple[str, str, str, i32, f64] = ("firstname", "middlename", "last name", -55, 3.14) + print(x) + print(y) + +test_print_tuple() +test_print_list_of_tuples() diff --git a/integration_tests/print_list_tuple_03.py b/integration_tests/print_list_tuple_03.py new file mode 100644 index 0000000000..25006696dd --- /dev/null +++ b/integration_tests/print_list_tuple_03.py @@ -0,0 +1,11 @@ +from lpython import i32 + +def f(): + # issue 1862 + x: dict[i32, tuple[i32, i32]] + x = {1: (1, 2), 2: (3, 4)} + y: dict[i32, list[i32]] + y = {1: [1, 2], 2: [3, 4]} + print(x[1], x[2], y[1]) + +f() diff --git a/integration_tests/recursive_01.py b/integration_tests/recursive_01.py index 9800bc4f26..b739255654 100644 --- a/integration_tests/recursive_01.py +++ b/integration_tests/recursive_01.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def fib(n: i32) -> i32: if n <= 1: diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py index af4b1b725a..e5df7cf909 100755 --- a/integration_tests/run_tests.py +++ b/integration_tests/run_tests.py @@ -6,10 +6,12 @@ # Initialization DEFAULT_THREADS_TO_USE = 8 # default no of threads is 8 -SUPPORTED_BACKENDS = ['llvm', 'c', 'wasm', 'cpython', 'x86', 'wasm_x86', 'wasm_x64'] +SUPPORTED_BACKENDS = ['llvm', 'c', 'wasm', 'cpython', 'x86', 'wasm_x86', 'wasm_x64', 'c_py', 'c_sym', 'cpython_sym', 'llvm_sym', 'llvm_py', 'llvm_jit'] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) LPYTHON_PATH = f"{BASE_DIR}/../src/bin" +fast_tests = "no" +python_libs_req = "no" def run_cmd(cmd, cwd=None): print(f"+ {cmd}") @@ -22,8 +24,8 @@ def run_cmd(cmd, cwd=None): def run_test(backend): run_cmd(f"mkdir {BASE_DIR}/_lpython-tmp-test-{backend}", cwd=BASE_DIR) cwd = f"{BASE_DIR}/_lpython-tmp-test-{backend}" - run_cmd(f"cmake -DKIND={backend} ..", cwd=cwd) - run_cmd(f"make -j{DEFAULT_THREADS_TO_USE}", cwd=cwd) + run_cmd(f"cmake -DKIND={backend} -DFAST={fast_tests} -DPYTHON_LIBS_REQ={python_libs_req} ..", cwd=cwd) + run_cmd(f"cmake --build . --parallel {DEFAULT_THREADS_TO_USE}", cwd=cwd) run_cmd(f"ctest -j{DEFAULT_THREADS_TO_USE} --output-on-failure", cwd=cwd) @@ -40,8 +42,10 @@ def get_args(): parser.add_argument("-j", "-n", "--no_of_threads", type=int, help="Parallel testing on given number of threads") parser.add_argument("-b", "--backends", nargs="*", default=["llvm", "cpython"], - type=str, help="Test the requested backends (%s)" % \ + type=str, help="Test the requested backends (%s), default: llvm, cpython" % \ ", ".join(SUPPORTED_BACKENDS)) + parser.add_argument("-f", "--fast", action='store_true', + help="Run supported tests with --fast") return parser.parse_args() @@ -49,14 +53,16 @@ def main(): args = get_args() # Setup - global DEFAULT_THREADS_TO_USE + global DEFAULT_THREADS_TO_USE, fast_tests, python_libs_req os.environ["PATH"] = LPYTHON_PATH + os.pathsep + os.environ["PATH"] # delete previously created directories (if any) for backend in SUPPORTED_BACKENDS: run_cmd(f"rm -rf {BASE_DIR}/_lpython-tmp-test-{backend}") DEFAULT_THREADS_TO_USE = args.no_of_threads or DEFAULT_THREADS_TO_USE + fast_tests = "yes" if args.fast else "no" for backend in args.backends: + python_libs_req = "yes" if backend in ["cpython", "c_py", "c_sym", "llvm_sym", 'llvm_py', 'llvm_jit'] else "no" test_backend(backend) diff --git a/integration_tests/sizeof_01.py b/integration_tests/sizeof_01.py index 10aae4437a..d6c042b50c 100644 --- a/integration_tests/sizeof_01.py +++ b/integration_tests/sizeof_01.py @@ -1,4 +1,4 @@ -from ltypes import sizeof, i64, i32, f32, f64, c32, c64, i16, ccall, CPtr +from lpython import sizeof, i64, i32, f32, f64, c32, c64, i16, ccall, CPtr @ccall def cmalloc(bytes: i64) -> CPtr: diff --git a/integration_tests/sizeof_02.py b/integration_tests/sizeof_02.py new file mode 100644 index 0000000000..40d34af64c --- /dev/null +++ b/integration_tests/sizeof_02.py @@ -0,0 +1,10 @@ +from sizeof_02_module import A +from lpython import i64, sizeof + +def get_sizeof() -> i64: + return sizeof(A) + +def test(): + print(get_sizeof()) + +test() diff --git a/integration_tests/sizeof_02_module.py b/integration_tests/sizeof_02_module.py new file mode 100644 index 0000000000..19aeb73705 --- /dev/null +++ b/integration_tests/sizeof_02_module.py @@ -0,0 +1,6 @@ +from lpython import i32, f32, dataclass + +@dataclass +class A: + x: i32 + y: f32 diff --git a/integration_tests/str_to_list_cast.py b/integration_tests/str_to_list_cast.py index 49db437d69..cff65fcce2 100644 --- a/integration_tests/str_to_list_cast.py +++ b/integration_tests/str_to_list_cast.py @@ -1,3 +1,5 @@ +from lpython import i32 + def f(): x: list[str] x = list("lpython") diff --git a/integration_tests/structs_01.py b/integration_tests/structs_01.py index cbf943867c..7ad860f5f2 100644 --- a/integration_tests/structs_01.py +++ b/integration_tests/structs_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64, dataclass +from lpython import i32, f32, f64, dataclass, InOut @dataclass class A: @@ -9,13 +9,12 @@ def f(a: A): print(a.x) print(a.y) -def change_struct(a: A): +def change_struct(a: InOut[A]): a.x = a.x + 1 a.y = a.y + f32(1) def g(): - x: A - x = A(f32(3.25), 3) + x: A = A(f32(3.25), 3) f(x) assert x.x == 3 assert f64(x.y) == 3.25 diff --git a/integration_tests/structs_02.py b/integration_tests/structs_02.py index 56a6a5217f..0e99458c34 100644 --- a/integration_tests/structs_02.py +++ b/integration_tests/structs_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer, ccallable, empty_c_void_p, f64 +from lpython import i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer, ccallable, empty_c_void_p, f64 @dataclass class A: @@ -9,17 +9,14 @@ class A: def f(a: CPtr) -> None: x: i32 y: f32 - a1: A + a1: A = A(3, f32(3.25)) a2: Pointer[A] - a1 = A(3, f32(3.25)) a2 = pointer(a1) print(a2, pointer(a1)) x = a2.x y = a2.y assert x == 3 assert f64(y) == 3.25 - a2 = c_p_pointer(a, A) - print(a, a2, pointer(a1)) def g(): b: CPtr = empty_c_void_p() diff --git a/integration_tests/structs_02b.py b/integration_tests/structs_02b.py new file mode 100644 index 0000000000..ed061ff6ce --- /dev/null +++ b/integration_tests/structs_02b.py @@ -0,0 +1,43 @@ +from lpython import (i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer, + ccallable, empty_c_void_p, f64, ccall, sizeof, i64) + +@ccall +def _lfortran_malloc(size: i32) -> CPtr: + pass + +def alloc(buf_size:i64) -> CPtr: + return _lfortran_malloc(i32(buf_size)) + +@ccallable +@dataclass +class A: + x: i32 + y: f32 + +@ccallable +def f(a: CPtr) -> None: + x: i32 + y: f32 + a1: A = A(3, f32(3.25)) + a2: Pointer[A] + a2 = pointer(a1) + print(a2, pointer(a1)) + # TODO: does not work: + #x = a2.x + #y = a2.y + #assert x == 3 + #assert f64(y) == 3.25 + a2 = c_p_pointer(a, A) + print(a, a2, pointer(a1)) + print(a2.x, a2.y) + assert a2.x == 5 + assert a2.y == f32(6.0) + +def g(): + b: CPtr = alloc(sizeof(A)) + b2: Pointer[A] = c_p_pointer(b, A) + b2.x = 5 + b2.y = f32(6) + f(b) + +g() diff --git a/integration_tests/structs_03.py b/integration_tests/structs_03.py index de92f83167..aa5e3214e2 100644 --- a/integration_tests/structs_03.py +++ b/integration_tests/structs_03.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64, dataclass, Pointer, pointer +from lpython import i32, f32, f64, dataclass, Pointer, pointer @dataclass class A: diff --git a/integration_tests/structs_04.py b/integration_tests/structs_04.py index ab3555b143..b1a1ad4307 100644 --- a/integration_tests/structs_04.py +++ b/integration_tests/structs_04.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64, dataclass +from lpython import i32, f32, f64, dataclass, field from copy import deepcopy @dataclass @@ -8,8 +8,8 @@ class A: @dataclass class B: - a: A z: i32 + a: A = field(default_factory=lambda: A(f32(0.0), 0)) def f(b: B): print(b.z, b.a.x, b.a.y) @@ -20,7 +20,7 @@ def f(b: B): def g(): a1: A = A(f32(1.0), 1) a2: A = A(f32(2.0), 2) - b: B = B(a1, 1) + b: B = B(1, a1) b.a = deepcopy(a2) b.z = 1 b.a.x = 2 diff --git a/integration_tests/structs_05.py b/integration_tests/structs_05.py index 233aa8190c..6ae6262ac7 100644 --- a/integration_tests/structs_05.py +++ b/integration_tests/structs_05.py @@ -1,4 +1,5 @@ -from ltypes import i32, f64, i64, i16, i8, f32, dataclass +from lpython import i32, f64, i64, i16, i8, f32, dataclass, InOut, Array +from numpy import empty @dataclass class A: @@ -10,7 +11,7 @@ class A: c: i8 d: bool -def verify(s: A[:], x1: i32, y1: f64, x2: i32, y2: f64): +def verify(s: Array[A, :], x1: i32, y1: f64, x2: i32, y2: f64): eps: f64 = 1e-12 s0: A = s[0] print(s0.x, s0.y, s0.z, s0.a, s0.b, s0.c, s0.d) @@ -32,7 +33,7 @@ def verify(s: A[:], x1: i32, y1: f64, x2: i32, y2: f64): assert s1.c == i8(x2) assert s1.d -def update_1(s: A): +def update_1(s: InOut[A]): s.x = 2 s.y = 1.2 s.z = i64(2) @@ -40,7 +41,7 @@ def update_1(s: A): s.b = i16(2) s.c = i8(2) -def update_2(s: A[:]): +def update_2(s: Array[A, :]): s[1].x = 3 s[1].y = 2.3 s[1].z = i64(3) @@ -49,9 +50,7 @@ def update_2(s: A[:]): s[1].c = i8(3) def g(): - # TODO: Replace y: A[2] with y: A[2] = [None, None] - # TODO: And enable cpython in integration_tests. - y: A[2] + y: Array[A, 2] = empty([2], dtype=A) y[0] = A(1.1, 1, i64(1), f32(1.1), i16(1), i8(1), True) y[1] = A(2.2, 2, i64(2), f32(2.2), i16(2), i8(2), True) verify(y, 1, 1.1, 2, 2.2) diff --git a/integration_tests/structs_06.py b/integration_tests/structs_06.py index 74a928a4ac..f82e026cdb 100644 --- a/integration_tests/structs_06.py +++ b/integration_tests/structs_06.py @@ -1,4 +1,4 @@ -from ltypes import i8, i32, i64, i8, i8, dataclass, packed +from lpython import i8, i32, i64, i8, i8, dataclass, packed @packed(aligned=1) @dataclass diff --git a/integration_tests/structs_07.py b/integration_tests/structs_07.py index 7d124ffb2e..3d0508ab3a 100644 --- a/integration_tests/structs_07.py +++ b/integration_tests/structs_07.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, i8, CPtr, sizeof, dataclass, ccall +from lpython import i32, i64, i8, CPtr, sizeof, dataclass, ccall @dataclass class A: diff --git a/integration_tests/structs_08.py b/integration_tests/structs_08.py index ba13e3e2db..0085334584 100644 --- a/integration_tests/structs_08.py +++ b/integration_tests/structs_08.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, dataclass, union, Union +from lpython import i32, i64, dataclass, union, Union from enum import Enum @union diff --git a/integration_tests/structs_09.py b/integration_tests/structs_09.py index ceff0277d5..9ba7139cbc 100644 --- a/integration_tests/structs_09.py +++ b/integration_tests/structs_09.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64, dataclass +from lpython import i32, f32, f64, dataclass, field @dataclass class C: @@ -7,13 +7,13 @@ class C: @dataclass class B: z: i32 - bc: C + bc: C = field(default_factory=lambda: C(f32(0.0))) @dataclass class A: y: f32 x: i32 - b: B + b: B = field(default_factory=lambda: B(0, C(f32(0.0)))) def f(a: A): @@ -22,8 +22,7 @@ def f(a: A): print(a.b.z) def g(): - x: A - x = A(f32(3.25), 3, B(71, C(f32(4.0)))) + x: A = A(f32(3.25), 3, B(71, C(f32(4.0)))) f(x) assert x.x == 3 assert f64(x.y) == 3.25 diff --git a/integration_tests/structs_10.py b/integration_tests/structs_10.py index bab2800e61..db067ed825 100644 --- a/integration_tests/structs_10.py +++ b/integration_tests/structs_10.py @@ -1,18 +1,18 @@ -from ltypes import i32, f64, dataclass +from lpython import i32, f64, dataclass, field from numpy import empty, float64 @dataclass class Mat: - mat: f64[2, 2] + mat: f64[2, 2] = field(default_factory=lambda: empty((2, 2), dtype=float64)) @dataclass class Vec: - vec: f64[2] + vec: f64[2] = field(default_factory=lambda: empty(2, dtype=float64)) @dataclass class MatVec: - mat: Mat - vec: Vec + mat: Mat = field(default_factory=lambda: Mat()) + vec: Vec = field(default_factory=lambda: Vec()) def rotate(mat_vec: MatVec) -> f64[2]: rotated_vec: f64[2] = empty(2, dtype=float64) diff --git a/integration_tests/structs_11.py b/integration_tests/structs_11.py index 4fc71e595e..1eea62eb75 100644 --- a/integration_tests/structs_11.py +++ b/integration_tests/structs_11.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, dataclass +from lpython import i32, f64, dataclass @dataclass class A: diff --git a/integration_tests/structs_12.py b/integration_tests/structs_12.py index cb48e11125..c7a2cfb715 100644 --- a/integration_tests/structs_12.py +++ b/integration_tests/structs_12.py @@ -1,4 +1,4 @@ -from ltypes import i32, i16, dataclass +from lpython import i32, i16, dataclass @dataclass class A: diff --git a/integration_tests/structs_13.py b/integration_tests/structs_13.py index 4a7bb51f32..9806fa1ac9 100644 --- a/integration_tests/structs_13.py +++ b/integration_tests/structs_13.py @@ -1,5 +1,8 @@ -from ltypes import i32, i16, i64, CPtr, dataclass, ccall, Pointer, c_p_pointer, sizeof +from lpython import (i32, i16, i64, CPtr, dataclass, ccall, Pointer, + c_p_pointer, sizeof, ccallable) +from numpy import array +@ccallable @dataclass class A: x: i32 @@ -23,7 +26,7 @@ def add_Aptr_members(Ax: i32, Ay: i16) -> i32: def test_A_member_passing(): array_cptr: CPtr = cmalloc(sizeof(A) * i64(10)) assert not bool(is_null(array_cptr)), "Failed to allocate array on memory" - array_ptr: Pointer[A[:]] = c_p_pointer(array_cptr, A[:]) + array_ptr: Pointer[A[:]] = c_p_pointer(array_cptr, A[:], array([10])) i: i32; sum_A_members: i32 for i in range(10): array_ptr[i] = A(i, i16(i + 1)) diff --git a/integration_tests/structs_14.py b/integration_tests/structs_14.py index 05e399758e..911ebc2094 100644 --- a/integration_tests/structs_14.py +++ b/integration_tests/structs_14.py @@ -1,4 +1,4 @@ -from ltypes import i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccallable, packed +from lpython import i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccallable, packed from numpy import empty, int8, int16, int32, int64, float32, complex64, complex128, float64 from copy import deepcopy @@ -71,7 +71,7 @@ def f(): buffer_.buffer3[i] = c32(i + 7) # buffer_clink_.buffer3 is a ctypes.Array # of type c_float_complex (a ctypes.Structure - # defined in ltypes.py) and c32(i + 8) is a + # defined in lpython.py) and c32(i + 8) is a # Python object. Python doesn't allow assigning # a Python object to ctypes.Structure. Hence, # the following line is commented out. diff --git a/integration_tests/structs_15.py b/integration_tests/structs_15.py index a7e9fc9c88..7341d42d60 100644 --- a/integration_tests/structs_15.py +++ b/integration_tests/structs_15.py @@ -1,5 +1,6 @@ -from ltypes import i32, i16, i8, i64, CPtr, dataclass, ccall, Pointer, c_p_pointer, sizeof +from lpython import i32, i16, i8, CPtr, dataclass, ccall, Pointer, c_p_pointer, sizeof, ccallable +@ccallable @dataclass class A: x: i16 diff --git a/integration_tests/structs_16.py b/integration_tests/structs_16.py index 1cb49e8e3f..6cf6e638d5 100644 --- a/integration_tests/structs_16.py +++ b/integration_tests/structs_16.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, dataclass, union, Union +from lpython import i32, i64, dataclass, union, Union @dataclass class A: diff --git a/integration_tests/structs_17.py b/integration_tests/structs_17.py index 10d9717451..30042f68f7 100644 --- a/integration_tests/structs_17.py +++ b/integration_tests/structs_17.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64, dataclass +from lpython import i32, f32, f64, dataclass, field @dataclass class B: @@ -6,13 +6,13 @@ class B: @dataclass class C: cz: f32 - bc: C + bc: C = field(default_factory=lambda: C(f32(0.0))) @dataclass class A: y: f32 x: i32 - b: B + b: B = field(default_factory=lambda: B(0, B.C(f32(0.0)))) def f(a: A): diff --git a/integration_tests/structs_18.py b/integration_tests/structs_18.py index 45ba10d1b5..d6a5fbd66b 100644 --- a/integration_tests/structs_18.py +++ b/integration_tests/structs_18.py @@ -1,4 +1,4 @@ -from ltypes import i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccallable, packed, ccall, CPtr, p_c_pointer, empty_c_void_p, pointer +from lpython import i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccallable, packed, ccall, CPtr, p_c_pointer, empty_c_void_p, pointer from numpy import empty, int8, int16, int32, int64, float32, complex64, complex128, float64 from copy import deepcopy diff --git a/integration_tests/structs_19.py b/integration_tests/structs_19.py index ac34ebf0a4..1ae675eb81 100644 --- a/integration_tests/structs_19.py +++ b/integration_tests/structs_19.py @@ -1,4 +1,4 @@ -from ltypes import (i8, dataclass, i32, f32, c32, f64, i16, i64, c64, +from lpython import (i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccall, CPtr, c_p_pointer, Pointer, ccallable) from numpy import empty, int32, int8, float32, float64, int16, int64, complex64, complex128 diff --git a/integration_tests/structs_20.py b/integration_tests/structs_20.py index 6270416cf1..0b26bb6398 100644 --- a/integration_tests/structs_20.py +++ b/integration_tests/structs_20.py @@ -1,4 +1,4 @@ -from ltypes import (i8, dataclass, i32, f32, c32, f64, i16, i64, c64, +from lpython import (i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccall, CPtr, c_p_pointer, Pointer, packed, ccallable) from numpy import empty, int8, int16, float32, complex64 diff --git a/integration_tests/structs_21.py b/integration_tests/structs_21.py index f8d3b4cfc7..26d83aee39 100644 --- a/integration_tests/structs_21.py +++ b/integration_tests/structs_21.py @@ -1,4 +1,4 @@ -from ltypes import i32, CPtr, dataclass, c_p_pointer, p_c_pointer, \ +from lpython import i32, CPtr, dataclass, c_p_pointer, p_c_pointer, \ pointer, empty_c_void_p, Pointer, ccallable @ccallable @@ -18,10 +18,19 @@ def f(c: CPtr): print(A) assert A == 3 +def g(c: CPtr): + i: i32 + for i in range(3): + p: Pointer[S] = c_p_pointer(c, S) + A: i32 = p.a + print(A) + assert A == 3 + def main(): s: S = S(3) p: CPtr = empty_c_void_p() p_c_pointer(pointer(s, S), p) f(p) + g(p) main() diff --git a/integration_tests/structs_22.py b/integration_tests/structs_22.py new file mode 100644 index 0000000000..7329d4c26b --- /dev/null +++ b/integration_tests/structs_22.py @@ -0,0 +1,43 @@ +from lpython import dataclass, i32, f64, u64 +from numpy import array + +@dataclass +class Foo: + x: i32 + y: i32 + +@dataclass +class Foo2: + p: f64 + q: i32 + r: u64 + +def main0() -> None: + foos: Foo[2] = array([Foo(1, 2), Foo(3, 4)]) + print(foos[0].x, foos[0].y, foos[1].x, foos[1].y) + + assert foos[0].x == 1 + assert foos[0].y == 2 + assert foos[1].x == 3 + assert foos[1].y == 4 + +def main1() -> None: + foos2: Foo2[3] = array([Foo2(-2.3, 42, u64(3)), Foo2(45.5, -3, u64(10001)), Foo2(1.0, -101, u64(100))]) + i: i32 + for i in range(3): + print(foos2[i].p, foos2[i].q, foos2[i].r) + + eps: f64 + eps = 1e-12 + assert abs(foos2[0].p - (-2.3)) <= eps + assert foos2[0].q == 42 + assert foos2[0].r == u64(3) + assert abs(foos2[1].p - (45.5)) <= eps + assert foos2[1].q == -3 + assert foos2[1].r == u64(10001) + assert abs(foos2[2].p - (1.0)) <= eps + assert foos2[2].q == -101 + assert foos2[2].r == u64(100) + +main0() +main1() diff --git a/integration_tests/structs_23.py b/integration_tests/structs_23.py new file mode 100644 index 0000000000..2e3950a48b --- /dev/null +++ b/integration_tests/structs_23.py @@ -0,0 +1,30 @@ +from lpython import dataclass, i32, u64, f64 + +@dataclass +class A: + a: i32 + b: i32 + +@dataclass +class B: + a: u64 + b: f64 + +def main0(): + s: A = A(b=-24, a=6) + print(s.a) + print(s.b) + + assert s.a == 6 + assert s.b == -24 + +def main1(): + s: B = B(u64(22), b=3.14) + print(s.a) + print(s.b) + + assert s.a == u64(22) + assert abs(s.b - 3.14) <= 1e-12 + +main0() +main1() diff --git a/integration_tests/structs_24.py b/integration_tests/structs_24.py new file mode 100644 index 0000000000..10bf76c890 --- /dev/null +++ b/integration_tests/structs_24.py @@ -0,0 +1,18 @@ +from lpython import dataclass, i32, f64, u64 +from numpy import array + +@dataclass +class Foo: + x: i32 + y: i32 + +def main0() -> None: + foos: Foo[2] = array([Foo(y=2, x=1), Foo(x=3, y=4)]) + print(foos[0].x, foos[0].y, foos[1].x, foos[1].y) + + assert foos[0].x == 1 + assert foos[0].y == 2 + assert foos[1].x == 3 + assert foos[1].y == 4 + +main0() diff --git a/integration_tests/structs_25.py b/integration_tests/structs_25.py new file mode 100644 index 0000000000..d5402c6c5d --- /dev/null +++ b/integration_tests/structs_25.py @@ -0,0 +1,20 @@ +from lpython import i32, dataclass, Array +from numpy import empty + +@dataclass +class Foo: + x: i32 + y: i32 + +def init(foos: Array[Foo, :]) -> None: + foos[0] = Foo(5, 21) + +def main0() -> None: + foos: Array[Foo, 1] = empty(1, dtype=Foo) + init(foos) + print("foos[0].x =", foos[0].x) + + assert foos[0].x == 5 + assert foos[0].y == 21 + +main0() diff --git a/integration_tests/structs_26.py b/integration_tests/structs_26.py new file mode 100644 index 0000000000..40cf3fdd4b --- /dev/null +++ b/integration_tests/structs_26.py @@ -0,0 +1,18 @@ +from lpython import dataclass, i32 + +@dataclass +class StringIO: + """Imitate the parts of io.StringIO we need.""" + _buf : str + _0cursor : i32 = 0 + _len : i32 = 0 + +def main0(): + io: StringIO = StringIO("random input xyz", 5, 24) + + print(io) + assert io._buf == "random input xyz" + assert io._0cursor == 5 + assert io._len == 24 + +main0() diff --git a/integration_tests/structs_27.py b/integration_tests/structs_27.py new file mode 100644 index 0000000000..4009794f48 --- /dev/null +++ b/integration_tests/structs_27.py @@ -0,0 +1,77 @@ +from lpython import dataclass, i32, u16, f32 + + +@dataclass +class StringIO: + _buf : str = '' + _0cursor : i32 = 10 + _len : i32 = 1 + +@dataclass +class StringIONew: + _buf : str + _0cursor : i32 = i32(142) + _len : i32 = i32(2439) + _var1 : u16 = u16(23) + _var2 : f32 = f32(30.24) + +#print("ok") + +def test_issue_1928(): + integer_asr : str = '(Integer 4 [])' + test_dude : StringIO = StringIO(integer_asr) + assert test_dude._buf == integer_asr + assert test_dude._len == 1 + assert test_dude._0cursor == 10 + test_dude._len = 100 + assert test_dude._len == 100 + test_dude._0cursor = 31 + assert test_dude._0cursor == 31 + + test_dude2 : StringIO = StringIO(integer_asr, 3) + assert test_dude2._buf == integer_asr + assert test_dude2._len == 1 + assert test_dude2._0cursor == 3 + test_dude2._len = 100 + assert test_dude2._len == 100 + test_dude2._0cursor = 31 + assert test_dude2._0cursor == 31 + + test_dude3 : StringIO = StringIO(integer_asr, 3, 5) + assert test_dude3._buf == integer_asr + assert test_dude3._len == 5 + assert test_dude3._0cursor == 3 + test_dude3._len = 100 + assert test_dude3._len == 100 + test_dude3._0cursor = 31 + assert test_dude3._0cursor == 31 + + test_dude4 : StringIO = StringIO() + assert test_dude4._buf == '' + assert test_dude4._len == 1 + assert test_dude4._0cursor == 10 + test_dude4._len = 100 + assert test_dude4._len == 100 + test_dude4._0cursor = 31 + assert test_dude4._0cursor == 31 + + +def test_issue_1981(): + integer_asr : str = '(Integer 4 [])' + test_dude : StringIONew = StringIONew(integer_asr) + assert test_dude._buf == integer_asr + assert test_dude._len == 2439 + assert test_dude._0cursor == 142 + assert test_dude._var1 == u16(23) + assert abs(test_dude._var2 - f32(30.24)) < f32(1e-5) + test_dude._len = 13 + test_dude._0cursor = 52 + test_dude._var1 = u16(34) + assert test_dude._buf == integer_asr + assert test_dude._len == 13 + assert test_dude._0cursor == 52 + assert test_dude._var1 == u16(34) + + +test_issue_1981() +test_issue_1928() diff --git a/integration_tests/structs_28.py b/integration_tests/structs_28.py new file mode 100644 index 0000000000..9e0f3bf502 --- /dev/null +++ b/integration_tests/structs_28.py @@ -0,0 +1,15 @@ +from lpython import dataclass, i32 + +@dataclass +class Pattern: + _foo : str + pass + _n: i32 + +def main0(): + p: Pattern = Pattern("some string", 5) + assert p._foo == "some string" + assert p._n == 5 + print(p) + +main0() diff --git a/integration_tests/structs_29.py b/integration_tests/structs_29.py new file mode 100644 index 0000000000..f78c7e2d94 --- /dev/null +++ b/integration_tests/structs_29.py @@ -0,0 +1,20 @@ +from lpython import dataclass, i32 + +@dataclass +class Foo: + x: i32 + y: i32 + + +def main0() -> None: + x: list[Foo] + y: Foo = Foo(0, 1) + z: Foo = Foo(1, 2) + x = [y, z] + i: i32 = 0 + for y in x: + assert y.x == i + assert y.y == i+1 + i += 1 + +main0() diff --git a/integration_tests/structs_30.py b/integration_tests/structs_30.py new file mode 100644 index 0000000000..83ad571a11 --- /dev/null +++ b/integration_tests/structs_30.py @@ -0,0 +1,15 @@ +from lpython import dataclass, i32 + +@dataclass +class Pattern: + _foo : str + ... + _n: i32 + +def main0(): + p: Pattern = Pattern("some string", 5) + assert p._foo == "some string" + assert p._n == 5 + print(p) + +main0() diff --git a/integration_tests/structs_31.py b/integration_tests/structs_31.py new file mode 100644 index 0000000000..472bf8d8d4 --- /dev/null +++ b/integration_tests/structs_31.py @@ -0,0 +1,22 @@ +from lpython import packed, dataclass, field, i32, InOut + +@packed +@dataclass +class inner_struct: + a: i32 + +@packed +@dataclass +class outer_struct: + b: inner_struct = field(default_factory=lambda: inner_struct(0)) + +def update_my_inner_struct(my_inner_struct: InOut[inner_struct]) -> None: + my_inner_struct.a = 99999 + +def main() -> None: + my_outer_struct: outer_struct = outer_struct() + + update_my_inner_struct(my_outer_struct.b) + assert my_outer_struct.b.a == 99999 + +main() diff --git a/integration_tests/structs_32.py b/integration_tests/structs_32.py new file mode 100644 index 0000000000..6e57217a87 --- /dev/null +++ b/integration_tests/structs_32.py @@ -0,0 +1,45 @@ +from lpython import packed, dataclass, field, i32, InOut + + +@packed +@dataclass +class inner_struct: + a: i32 + + +@packed +@dataclass +class outer_struct: + b: inner_struct = field(default_factory=lambda: inner_struct(0)) + + +def update_my_inner_struct(my_inner_struct: InOut[inner_struct]) -> None: + my_inner_struct.a = 99999 + + +def update_my_outer_struct(my_outer_struct: InOut[outer_struct]) -> None: + my_outer_struct.b.a = 12345 + + +def main() -> None: + my_outer_struct: outer_struct = outer_struct() + my_inner_struct: inner_struct = my_outer_struct.b + + assert my_outer_struct.b.a == 0 + + my_outer_struct.b.a = 12345 + assert my_outer_struct.b.a == 12345 + + my_outer_struct.b.a = 0 + assert my_outer_struct.b.a == 0 + + update_my_outer_struct(my_outer_struct) + assert my_outer_struct.b.a == 12345 + + my_inner_struct.a = 1111 + assert my_inner_struct.a == 1111 + + update_my_inner_struct(my_inner_struct) + assert my_inner_struct.a == 99999 + +main() diff --git a/integration_tests/structs_33.py b/integration_tests/structs_33.py new file mode 100644 index 0000000000..24a537447a --- /dev/null +++ b/integration_tests/structs_33.py @@ -0,0 +1,24 @@ +from lpython import packed, dataclass, field, i32 + +# test issue 2125 + +@packed +@dataclass +class inner_struct: + inner_field: i32 = 0 + + +@packed +@dataclass +class outer_struct: + inner_s : inner_struct = field(default_factory=lambda: inner_struct()) + + +def check() -> None: + outer_struct_instance : outer_struct = outer_struct(inner_struct(5)) + outer_struct_instance2 : outer_struct = outer_struct_instance + inner_struct_instance : inner_struct = outer_struct_instance2.inner_s + assert inner_struct_instance.inner_field == 5 + + +check() diff --git a/integration_tests/structs_34.py b/integration_tests/structs_34.py new file mode 100644 index 0000000000..f69d6d5f6a --- /dev/null +++ b/integration_tests/structs_34.py @@ -0,0 +1,24 @@ +from lpython import packed, dataclass, ccallable, i32, ccallback + +@ccallable +@packed +@dataclass +class struct_0: + val_0 : i32 = 613 + +@ccallable +@packed +@dataclass +class struct_1: + val_1 : struct_0 = struct_0() + +def print_val_0_in_struct_0(struct_0_instance : struct_0) -> i32: + print(struct_0_instance.val_0) + return 0 + +@ccallback +def entry_point() -> i32: + struct_1_instance : struct_1 = struct_1() + return print_val_0_in_struct_0(struct_1_instance.val_1) + +assert entry_point() == 0 diff --git a/integration_tests/structs_35.py b/integration_tests/structs_35.py new file mode 100644 index 0000000000..4bdb499d75 --- /dev/null +++ b/integration_tests/structs_35.py @@ -0,0 +1,26 @@ +from lpython import dataclass, field, i32 +from numpy import array + +@dataclass +class X: + a: i32 = 123 + b: bool = True + c: list[i32] = field(default_factory=lambda: [1, 2, 3]) + d: i32[3] = field(default_factory=lambda: array([4, 5, 6])) + e: i32 = field(default=-5) + +def main0(): + x: X = X() + print(x) + assert x.a == 123 + assert x.b == True + assert x.c[0] == 1 + assert x.d[1] == 5 + assert x.e == -5 + x.c[0] = 3 + x.d[0] = 3 + print(x) + assert x.c[0] == 3 + assert x.d[0] == 3 + +main0() diff --git a/integration_tests/symbolics_01.py b/integration_tests/symbolics_01.py new file mode 100644 index 0000000000..ae0dab1dd4 --- /dev/null +++ b/integration_tests/symbolics_01.py @@ -0,0 +1,22 @@ +from sympy import Symbol, pi +from lpython import S + +def main0(): + x: S = Symbol('x') + y: S = Symbol('y') + x = pi + z: S = x + y + x = z + print(x) + print(z) + assert(x == z) + assert(z == pi + y) + assert(z != S(2)*pi + y) + + # testing PR 2404 + p: S = Symbol('pi') + print(p) + print(p != pi) + assert(p != pi) + +main0() \ No newline at end of file diff --git a/integration_tests/symbolics_02.py b/integration_tests/symbolics_02.py new file mode 100644 index 0000000000..7650b11d2d --- /dev/null +++ b/integration_tests/symbolics_02.py @@ -0,0 +1,123 @@ +from sympy import Symbol, pi, Add, Mul, Pow +from lpython import S + +def test_symbolic_operations(): + x: S = Symbol('x') + y: S = Symbol('y') + pi1: S = pi + pi2: S = pi + + # Addition + z: S = x + y + z1: bool = z.func == Add + z2: bool = z.func == Mul + assert(z == x + y) + assert(z1 == True) + assert(z2 == False) + if z.func == Add: + assert True + else: + assert False + assert(z.func == Add) + assert(z.args[0] == x or z.args[0] == y) + assert(z.args[1] == y or z.args[1] == x) + print(z) + + # Subtraction + w: S = x - y + w1: bool = w.func == Add + assert(w == x - y) + assert(w1 == True) + if w.func == Add: + assert True + else: + assert False + assert(w.func == Add) + print(w) + + # Multiplication + u: S = x * y + u1: bool = u.func == Mul + assert(u == x * y) + assert(u1 == True) + if u.func == Mul: + assert True + else: + assert False + assert(u.func == Mul) + assert(u.args[0] == x) + assert(u.args[1] == y) + print(u) + + # Division + v: S = x / y + v1: bool = v.func == Mul + assert(v == x / y) + assert(v1 == True) + if v.func == Mul: + assert True + else: + assert False + assert(v.func == Mul) + print(v) + + # Power + p: S = x ** y + p1: bool = p.func == Pow + p2: bool = p.func == Add + p3: bool = p.func == Mul + assert(p == x ** y) + assert(p1 == True) + assert(p2 == False) + assert(p3 == False) + if p.func == Pow: + assert True + else: + assert False + assert(p.func == Pow) + print(p) + + # Casting + a: S = S(100) + b: S = S(-100) + c: S = a + b + assert(c == S(0)) + print(c) + + # Comparison + b1: bool = pi1 == pi2 + print(b1) + assert(b1 == True) + b2: bool = pi1 != pi + print(b2) + assert(b2 == False) + b3: bool = pi1 != x + print(b3) + assert(b3 == True) + b4: bool = pi == Symbol("x") + print(b4) + assert(b4 == False) + + # is_integer check + assert(pi1.is_integer == False) + assert(a.is_integer == True) + assert(c.is_integer == True) + + # is_positive check + assert(a.is_positive == True) + assert(b.is_positive == False) + assert(c.is_positive == False) + + # logical binop check + l1: bool = True and p.func == Pow + l2: bool = False or p.func == Pow + l3: bool = False and u.func == Mul + l4: bool = True or u.func == Add + if p.func == Pow and u.func == Mul: + print(True) + assert(l1) + assert(l2) + assert(not l3) + assert(l4) + +test_symbolic_operations() diff --git a/integration_tests/symbolics_03.py b/integration_tests/symbolics_03.py new file mode 100644 index 0000000000..8dc91a9720 --- /dev/null +++ b/integration_tests/symbolics_03.py @@ -0,0 +1,24 @@ +from sympy import Symbol, pi +from lpython import S + +def test_operator_chaining(): + w: S = S(2) + x: S = Symbol('x') + y: S = Symbol('y') + z: S = Symbol('z') + + a: S = x * w + b: S = a + pi + c: S = b / z + d: S = c ** w + + assert(a == S(2)*x) + assert(b == pi + S(2)*x) + assert(c == (pi + S(2)*x)/z) + assert(d == (pi + S(2)*x)**S(2)/z**S(2)) + print(a) # Expected: 2*x + print(b) # Expected: pi + 2*x + print(c) # Expected: (pi + 2*x)/z + print(d) # Expected: (pi + 2*x)**2/z**2 + +test_operator_chaining() \ No newline at end of file diff --git a/integration_tests/symbolics_04.py b/integration_tests/symbolics_04.py new file mode 100644 index 0000000000..63d30bf3f6 --- /dev/null +++ b/integration_tests/symbolics_04.py @@ -0,0 +1,41 @@ +from sympy import Symbol, pi, S +from lpython import S + +def test_chained_operations(): + x: S = Symbol('x') + y: S = Symbol('y') + z: S = Symbol('z') + a: S = Symbol('a') + b: S = Symbol('b') + + # Chained Operations + w: S = (x + y) * ((a - b) / (pi + z)) + result: S = (w ** S(2) - pi) + S(3) + + # Print Statements + assert(result == S(3) + (a -b)**S(2)*(x + y)**S(2)/(z + pi)**S(2) - pi) + print(result) + + # Additional Variables + c: S = Symbol('c') + d: S = Symbol('d') + e: S = Symbol('e') + f: S = Symbol('f') + + # Chained Operations with Additional Variables + x = (c * d + e) / f + y = (x - S(10)) * (pi + S(5)) + z = y ** (S(2) / (f + d)) + result = (z + e) * (a - b) + + # Print Statements + assert(result == (a - b)*(e + ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f)))) + print(result) + assert(x == (e + c*d)/f) + print(x) + assert(y == (S(5) + pi)*(S(-10) + (e + c*d)/f)) + print(y) + assert(z == ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f))) + print(z) + +test_chained_operations() \ No newline at end of file diff --git a/integration_tests/symbolics_05.py b/integration_tests/symbolics_05.py new file mode 100644 index 0000000000..b503bbcdda --- /dev/null +++ b/integration_tests/symbolics_05.py @@ -0,0 +1,51 @@ +from sympy import Symbol, expand, diff, sin, cos, exp, pi +from lpython import S + +def test_operations(): + x: S = Symbol('x') + y: S = Symbol('y') + z: S = Symbol('z') + a: S = (x + y)**S(2) + b: S = (x + y + z)**S(3) + + # test expand + assert(a.expand() == S(2)*x*y + x**S(2) + y**S(2)) + assert(expand(b) == S(3)*x*y**S(2) + S(3)*x*z**S(2) + S(3)*x**S(2)*y + S(3)*x**S(2)*z +\ + S(3)*y*z**S(2) + S(3)*y**S(2)*z + S(6)*x*y*z + x**S(3) + y**S(3) + z**S(3)) + print(a.expand()) + print(expand(b)) + + # test diff + assert(a.diff(x) == S(2)*(x + y)) + assert(diff(b, x) == S(3)*(x + y + z)**S(2)) + print(a.diff(x)) + print(diff(b, x)) + + # test diff 2 + c:S = sin(x) + d:S = cos(x) + assert(sin(Symbol("x")).diff(x) == d) + assert(sin(x).diff(Symbol("x")) == d) + assert(sin(x).diff(x) == d) + assert(sin(x).diff(x).diff(x) == S(-1)*c) + assert(sin(x).expand().diff(x).diff(x) == S(-1)*c) + assert((sin(x) + cos(x)).diff(x) == S(-1)*c + d) + assert((sin(x) + cos(x) + exp(x) + pi).diff(x).expand().diff(x) == exp(x) + S(-1)*c + S(-1)*d) + + # test args + assert(a.args[0] == x + y) + assert(a.args[1] == S(2)) + assert(b.args[0] == x + y + z) + assert(b.args[1] == S(3)) + assert(c.args[0] == x) + assert(d.args[0] == x) + + # test subs + b1: S = b.subs(x, y) + b1 = b1.subs(z, y) + assert(a.subs(x, y) == S(4)*y**S(2)) + assert(b1 == S(27)*y**S(3)) + assert(c.subs(x, y) == sin(y)) + assert(d.subs(x, z) == cos(z)) + +test_operations() \ No newline at end of file diff --git a/integration_tests/symbolics_06.py b/integration_tests/symbolics_06.py new file mode 100644 index 0000000000..f56d76c80d --- /dev/null +++ b/integration_tests/symbolics_06.py @@ -0,0 +1,58 @@ +from sympy import Symbol, sin, cos, exp, log, Abs, pi, diff, sign +from lpython import S + +def test_elementary_functions(): + + # test sin, cos + x: S = Symbol('x') + assert(sin(pi) == S(0)) + assert(sin(pi/S(2)) == S(1)) + assert(sin(S(2)*pi) == S(0)) + assert(cos(pi) == S(-1)) + assert(cos(pi/S(2)) == S(0)) + assert(cos(S(2)*pi) == S(1)) + assert(diff(sin(x), x) == cos(x)) + assert(diff(cos(x), x) == S(-1)*sin(x)) + + # test exp, log + assert(exp(S(0)) == S(1)) + assert(log(S(1)) == S(0)) + assert(diff(exp(x), x) == exp(x)) + assert(diff(log(x), x) == S(1)/x) + + # test Abs + assert(Abs(S(-10)) == S(10)) + assert(Abs(S(10)) == S(10)) + assert(Abs(S(-1)*x) == Abs(x)) + + # test sign + assert(sign(S(-10)) == S(-1)) + assert(sign(S(0)) == S(0)) + assert(sign(S(10)) == S(1)) + assert(sign(S(2)* x) == sign(x)) + assert(sign(S(-1)* x) == S(-1) * sign(x)) + + # test composite functions + a: S = exp(x) + b: S = sin(a) + b1: bool = b.func == sin + c: S = cos(b) + d: S = log(c) + d1: bool = d.func == log + e: S = Abs(d) + print(e) + assert(b1 == True) + if b.func == sin: + assert True + else: + assert False + assert(b.func == sin) + assert(d1 == True) + if d.func == log: + assert True + else: + assert False + assert(d.func == log) + assert(e == Abs(log(cos(sin(exp(x)))))) + +test_elementary_functions() \ No newline at end of file diff --git a/integration_tests/symbolics_07.py b/integration_tests/symbolics_07.py new file mode 100644 index 0000000000..f6d9ea947f --- /dev/null +++ b/integration_tests/symbolics_07.py @@ -0,0 +1,23 @@ +from lpython import ccall, CPtr +import os + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_new_heap() -> CPtr: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_const_pi(x: CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_str(x: CPtr) -> str: + pass + +def main0(): + x: CPtr = basic_new_heap() + basic_const_pi(x) + s: str = basic_str(x) + print(s) + assert s == "pi" + +main0() diff --git a/integration_tests/symbolics_08.py b/integration_tests/symbolics_08.py new file mode 100644 index 0000000000..15e010d160 --- /dev/null +++ b/integration_tests/symbolics_08.py @@ -0,0 +1,31 @@ +from lpython import ccall, CPtr, p_c_pointer, pointer, i64, empty_c_void_p +import os + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_new_stack(x: CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_free_stack(x: CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_const_pi(x: CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_str(x: CPtr) -> str: + pass + +def main0(): + y: i64 = i64(0) + x: CPtr = empty_c_void_p() + p_c_pointer(pointer(y, i64), x) + basic_new_stack(x) + basic_const_pi(x) + s: str = basic_str(x) + print(s) + assert s == "pi" + basic_free_stack(x) + +main0() \ No newline at end of file diff --git a/integration_tests/symbolics_09.py b/integration_tests/symbolics_09.py new file mode 100644 index 0000000000..18567769a4 --- /dev/null +++ b/integration_tests/symbolics_09.py @@ -0,0 +1,21 @@ +from sympy import Symbol, pi, sin, cos +from lpython import S, i32 + +def addInteger(x: S, y: S, z: S, i: i32): + _i: S = S(i) + print(x + y + z + _i) + +def call_addInteger(): + a: S = Symbol("x") + b: S = Symbol("y") + c: S = pi + d: S = sin(a) + e: S = cos(b) + addInteger(c, d, e, 2) + addInteger(c, sin(a), cos(b), 2) + addInteger(pi, sin(Symbol("x")), cos(Symbol("y")), 2) + +def main0(): + call_addInteger() + +main0() diff --git a/integration_tests/symbolics_10.py b/integration_tests/symbolics_10.py new file mode 100644 index 0000000000..c833c1e59f --- /dev/null +++ b/integration_tests/symbolics_10.py @@ -0,0 +1,26 @@ +from sympy import Symbol, sin, pi +from lpython import S + +def test_attributes(): + w: S = pi + x: S = Symbol('x') + y: S = Symbol('y') + z: S = sin(x) + + # test has + assert(w.has(x) == False) + assert(y.has(x) == False) + assert(x.has(x) == True) + assert(x.has(x) == z.has(x)) + + # test has 2 + assert(sin(x).has(x) == True) + assert(sin(x).has(y) == False) + assert(sin(Symbol("x")).has(x) == True) + assert(sin(Symbol("x")).has(y) == False) + assert(sin(Symbol("x")).has(Symbol("x")) == True) + assert(sin(Symbol("x")).has(Symbol("y")) == False) + assert(sin(Symbol("x")).has(Symbol("x")) != sin(Symbol("x")).has(Symbol("y"))) + assert(sin(Symbol("x")).has(Symbol("x")) == sin(Symbol("y")).has(Symbol("y"))) + +test_attributes() \ No newline at end of file diff --git a/integration_tests/symbolics_11.py b/integration_tests/symbolics_11.py new file mode 100644 index 0000000000..49696c09c2 --- /dev/null +++ b/integration_tests/symbolics_11.py @@ -0,0 +1,19 @@ +from sympy import Symbol, sin, pi +from lpython import S + +def test_extraction_of_elements(): + x: S = Symbol("x") + l1: list[S] = [x, pi, sin(x), Symbol("y")] + ele1: S = l1[0] + ele2: S = l1[1] + ele3: S = l1[2] + ele4: S = l1[3] + + assert(ele1 == x) + assert(ele2 == pi) + assert(ele3 == sin(x)) + assert(ele4 == Symbol("y")) + print(ele1, ele2, ele3, ele4) + print(l1[0], l1[1], l1[2], l1[3]) + +test_extraction_of_elements() diff --git a/integration_tests/symbolics_12.py b/integration_tests/symbolics_12.py new file mode 100644 index 0000000000..05711e2b1e --- /dev/null +++ b/integration_tests/symbolics_12.py @@ -0,0 +1,70 @@ +from sympy import Symbol, E, log, exp, oo +from lpython import S + +def main0(): + # Testing out symbolic constants like E, oo etc + + # Define symbolic variables + x: S = Symbol('x') + y: S = Symbol('y') + + # Assign E to the variable x + x = E + + # Check if x is equal to E + assert x == E + + # Perform some symbolic operations + z: S = x + y + + # Check if z is equal to E + y + assert z == E + y + + # Check if x is not equal to 2E + y + assert x != S(2) * E + y + + # Evaluate some mathematical expressions + expr1: S = log(E) + expr2: S = exp(S(1)) + + # Check the results + assert expr1 == S(1) + assert expr2 == E ** S(1) + + # Print the results + print("x = ", x) + print("z = ", z) + print("log(E) = ", expr1) + print("exp(1) = ", expr2) + + # Test symbolic infinity constant + inf: S = oo + + # Check if inf is equal to oo + assert inf == oo + + # Perform some symbolic operations with oo + z = x + inf + + # Check if z is equal to x + oo + assert z == x + oo + + # Check if x is not equal to 2 * oo + y + assert x != S(2) * oo + y + + # Evaluate some mathematical expressions with oo + expr1 = log(oo) + expr2 = exp(oo) + + # Check the results + assert expr1 == oo + assert expr2 == oo + + # Print the results + print("inf = ", inf) + print("z = ", z) + print("log(oo) = ", expr1) + print("exp(oo) = ", expr2) + + +main0() diff --git a/integration_tests/symbolics_13.py b/integration_tests/symbolics_13.py new file mode 100644 index 0000000000..6494d28a40 --- /dev/null +++ b/integration_tests/symbolics_13.py @@ -0,0 +1,12 @@ +from lpython import S +from sympy import pi + +def func() -> S: + return pi + +def test_func(): + z: S = func() + print(z) + assert z == pi + +test_func() diff --git a/integration_tests/symbolics_14.py b/integration_tests/symbolics_14.py new file mode 100644 index 0000000000..f99ad7aa39 --- /dev/null +++ b/integration_tests/symbolics_14.py @@ -0,0 +1,15 @@ +from lpython import S +from sympy import Symbol + +def mmrv(x: S) -> list[S]: + l1: list[S] = [x] + return l1 + +def test_mrv1(): + x: S = Symbol("x") + ans: list[S] = mmrv(x) + element_1: S = ans[0] + print(element_1) + assert element_1 == x + +test_mrv1() \ No newline at end of file diff --git a/integration_tests/symbolics_15.py b/integration_tests/symbolics_15.py new file mode 100644 index 0000000000..096f7c442d --- /dev/null +++ b/integration_tests/symbolics_15.py @@ -0,0 +1,72 @@ +from lpython import ccall, CPtr, p_c_pointer, pointer, i64, empty_c_void_p, Out +import os + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_new_stack(x: CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_new_heap() -> CPtr: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_const_pi(x: CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_assign(x: CPtr, y:CPtr) -> None: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_str(x: CPtr) -> str: + pass + +@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib") +def basic_free_stack(x: CPtr) -> None: + pass + +def mmrv(r: Out[list[CPtr]]) -> None: + # x: S = pi + _x: i64 = i64(0) + x: CPtr = empty_c_void_p() + p_c_pointer(pointer(_x, i64), x) + basic_new_stack(x) + basic_const_pi(x) + + # l1: list[S] = [x] + _l1: list[CPtr] = [x] + l1: list[CPtr] = [] + + i: i32 = 0 + for i in range(len(_l1)): + tmp: CPtr = basic_new_heap() + l1.append(tmp) + basic_assign(l1[0], x) + + # print(l1[0]) + s1: str = basic_str(l1[0]) + print(s1) + assert s1 == "pi" + + # r = l1 + r = l1 + + basic_free_stack(x) + +def test_mrv(): + # ans : list[S] + # temp : list[S] + ans: list[CPtr] + temp: list[CPtr] + + # mmrv(ans) + # temp = ans + mmrv(ans) + temp = ans + + # print(temp[0]) + s2: str = basic_str(temp[0]) + print(s2) + assert s2 == "pi" + +test_mrv() \ No newline at end of file diff --git a/integration_tests/symbolics_16.py b/integration_tests/symbolics_16.py new file mode 100644 index 0000000000..abdaa2c92b --- /dev/null +++ b/integration_tests/symbolics_16.py @@ -0,0 +1,18 @@ +from lpython import S +from sympy import Symbol, pi, sin + +def mmrv() -> list[S]: + x: S = Symbol('x') + l1: list[S] = [pi, sin(x)] + return l1 + +def test_mrv1(): + ans: list[S] = mmrv() + element_1: S = ans[0] + element_2: S = ans[1] + assert element_1 == pi + assert element_2 == sin(Symbol('x')) + print(element_1, element_2) + + +test_mrv1() \ No newline at end of file diff --git a/integration_tests/symbolics_17.py b/integration_tests/symbolics_17.py new file mode 100644 index 0000000000..74494e8049 --- /dev/null +++ b/integration_tests/symbolics_17.py @@ -0,0 +1,10 @@ +from lpython import S +from sympy import Symbol, pi + +def test_main(): + x: S = Symbol('x') + if x != pi: + print(x != pi) + assert x != pi + +test_main() \ No newline at end of file diff --git a/integration_tests/symbolics_18.py b/integration_tests/symbolics_18.py new file mode 100644 index 0000000000..b3dd8bad2c --- /dev/null +++ b/integration_tests/symbolics_18.py @@ -0,0 +1,36 @@ +from lpython import S +from sympy import Symbol, log + +def func_01(e: S, x: S) -> S: + print(e) + if e == x: + return x + print(e) + return e + +def test_func_01(): + x: S = Symbol("x") + ans: S = func_01(log(x), x) + print(ans) + +def func_02(e: S, x: S) -> list[S]: + print(e) + if e == x: + list1: list[S] = [x] + return list1 + else: + print(e) + list2: list[S] = func_02(x, x) + return list2 + +def test_func_02(): + x: S = Symbol("x") + ans: list[S] = func_02(log(x), x) + ele: S = ans[0] + print(ele) + +def tests(): + test_func_01() + test_func_02() + +tests() \ No newline at end of file diff --git a/integration_tests/test_01_goto.py b/integration_tests/test_01_goto.py deleted file mode 100644 index 2857c01768..0000000000 --- a/integration_tests/test_01_goto.py +++ /dev/null @@ -1,35 +0,0 @@ -from ltypes import with_goto, i32 - -@with_goto -def f() -> i32: - i:i32 - for i in range(10): - if i == 5: - goto .end - - label .end - assert i == 5 - return i - -@with_goto -def g(size: i32) -> i32: - i:i32 - - i = 0 - label .loop - if i >= size: - goto .end - i += 1 - goto .loop - - label .end - return i - -def test_goto(): - print(f()) - print(g(10)) - print(g(20)) - assert g(30) == 30 - assert g(40) == 40 - -test_goto() diff --git a/integration_tests/test_ConstantEllipsis b/integration_tests/test_ConstantEllipsis new file mode 100644 index 0000000000..58222aa9eb --- /dev/null +++ b/integration_tests/test_ConstantEllipsis @@ -0,0 +1,13 @@ +from lpython import i32 + +def test_Ellipsis_Function(): + ... + +def test_Ellipsis_For(): + i:i32 + for i in range(5): + ... + +def main0(): + test_Ellipsis_Function() + test_Ellipsis_For() \ No newline at end of file diff --git a/integration_tests/test_argv_01.py b/integration_tests/test_argv_01.py index d22b468e37..c7ba747072 100644 --- a/integration_tests/test_argv_01.py +++ b/integration_tests/test_argv_01.py @@ -1,12 +1,22 @@ -from ltypes import i32 -from sys import _lpython_argv +from lpython import i32 +from sys import argv def test(): - exe: str = _lpython_argv()[0] - i: i32 - for i in range(len(exe)-1, 0, -1): - if exe[i] == '/': + exe: str = argv[0] + res: str = "" + + if exe[0] == '.': + exe = exe[1:len(exe)] + + s: str + for s in exe: + if s == '.': break - assert exe[i+1:len(exe)] == 'test_argv_01' + if s == '/': + res = "" + else: + res += s + + assert res == 'test_argv_01' test() diff --git a/integration_tests/test_attributes.py b/integration_tests/test_attributes.py new file mode 100644 index 0000000000..f42775b678 --- /dev/null +++ b/integration_tests/test_attributes.py @@ -0,0 +1,12 @@ +def test_attributes() -> None: + a: i32 = 10 + assert a.bit_length() == 4 + + b: str = 'abc' + assert b.upper() == 'ABC' + + c: list[i32] = [10, 20, 30] + assert c[0].bit_length() == 4 + assert c.index(10) == 0 + +test_attributes() diff --git a/integration_tests/test_bit_length.py b/integration_tests/test_bit_length.py index 68bccae13f..8c64a4682d 100644 --- a/integration_tests/test_bit_length.py +++ b/integration_tests/test_bit_length.py @@ -1,5 +1,5 @@ from math import floor, log2 -from ltypes import i8, i32, i16 +from lpython import i8, i32, i16 def ff(): assert -8 .bit_length() == -4 @@ -24,8 +24,25 @@ def ff3(): x = -i16(one << i16(13)) assert i32(x.bit_length()) == 14 +def ff4(): + print((-100).bit_length()) + print((-4).bit_length()) + + assert (-100).bit_length() == 7 + assert (-4).bit_length() == 3 + +def ff5(): + a: i32 + a = 100 + print((-a).bit_length()) + print((-(-(-(-a)))).bit_length()) + + assert (-a).bit_length() == 7 + assert (-(-(-(-a)))).bit_length() == 7 ff() ff1() ff2() ff3() +ff4() +ff5() diff --git a/integration_tests/test_bool_binop.py b/integration_tests/test_bool_binop.py index 98e817b2fa..e869e8f060 100644 --- a/integration_tests/test_bool_binop.py +++ b/integration_tests/test_bool_binop.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def f(): i: i32 diff --git a/integration_tests/test_builtin.py b/integration_tests/test_builtin.py index a57a27599c..7df13c3833 100644 --- a/integration_tests/test_builtin.py +++ b/integration_tests/test_builtin.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_ord(): s: str @@ -163,10 +163,34 @@ def test_chr(): assert(chr(125) == '}') # testing compile time implementation assert(right_brace == '}') # testing runtime implementation +def more_test(): + p: i32 + q: i32 + r: i32 + s: i32 + p = 97 # char 'a' + q = 112 # char 'p' + r = 10 # newline char + s = 65 # char 'A' + + print(chr(p)) + print(chr(q)) + print(chr(r)) + print(chr(s)) + + a: str + b: str + c: str + d: str + a = "!" + b = " " + c = "Z" + d = "g" + print(ord(a)) + print(ord(b)) + print(ord(c)) + print(ord(d)) test_ord() test_chr() - - - - +more_test() diff --git a/integration_tests/test_builtin_abs.py b/integration_tests/test_builtin_abs.py index 1186b832ce..73f1820f18 100644 --- a/integration_tests/test_builtin_abs.py +++ b/integration_tests/test_builtin_abs.py @@ -1,4 +1,4 @@ -from ltypes import f32, f64, i32, i64, i8, i16 +from lpython import f32, f64, i32, i64, i8, i16 def test_abs(): x: f64 @@ -32,8 +32,8 @@ def test_abs(): b: bool b = True - assert abs(b) == 1 + assert abs(i32(b)) == 1 b = False - assert abs(b) == 0 + assert abs(i32(b)) == 0 test_abs() diff --git a/integration_tests/test_builtin_bin.py b/integration_tests/test_builtin_bin.py index ce38dd7cc4..b8c3f20e5a 100644 --- a/integration_tests/test_builtin_bin.py +++ b/integration_tests/test_builtin_bin.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_bin(): i: i32 diff --git a/integration_tests/test_builtin_bool.py b/integration_tests/test_builtin_bool.py index 03b68f592c..fee923a1f2 100644 --- a/integration_tests/test_builtin_bool.py +++ b/integration_tests/test_builtin_bool.py @@ -1,4 +1,4 @@ -from ltypes import i8, i16, i32, i64, f32, f64, c32, c64 +from lpython import i8, i16, i32, i64, f32, f64, c32, c64 def test_bool(): a: i32 diff --git a/integration_tests/test_builtin_divmod.py b/integration_tests/test_builtin_divmod.py index 7a2713a565..9296e0605d 100644 --- a/integration_tests/test_builtin_divmod.py +++ b/integration_tests/test_builtin_divmod.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def f(): i: i32 = 42356 diff --git a/integration_tests/test_builtin_float.py b/integration_tests/test_builtin_float.py index f2b2ea20ec..9b28b0b61a 100644 --- a/integration_tests/test_builtin_float.py +++ b/integration_tests/test_builtin_float.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, f64 +from lpython import i32, f32, f64 def test_float(): i: i32 diff --git a/integration_tests/test_builtin_hex.py b/integration_tests/test_builtin_hex.py index 38ae1b0d7b..bf63d59f48 100644 --- a/integration_tests/test_builtin_hex.py +++ b/integration_tests/test_builtin_hex.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_hex(): i: i32 diff --git a/integration_tests/test_builtin_int.py b/integration_tests/test_builtin_int.py index a1deb495ed..248a82c100 100644 --- a/integration_tests/test_builtin_int.py +++ b/integration_tests/test_builtin_int.py @@ -1,4 +1,4 @@ -from ltypes import f64, i32, i64 +from lpython import f64, i32, i64 def test_int(): f: f64 diff --git a/integration_tests/test_builtin_len.py b/integration_tests/test_builtin_len.py index 70f5ea9f98..8da4a0dfc5 100644 --- a/integration_tests/test_builtin_len.py +++ b/integration_tests/test_builtin_len.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def test_len(): s: str diff --git a/integration_tests/test_builtin_oct.py b/integration_tests/test_builtin_oct.py index 516ee9933c..5613323f1f 100644 --- a/integration_tests/test_builtin_oct.py +++ b/integration_tests/test_builtin_oct.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_oct(): i: i32 diff --git a/integration_tests/test_builtin_pow.py b/integration_tests/test_builtin_pow.py index f2869e10f5..3ee942a167 100644 --- a/integration_tests/test_builtin_pow.py +++ b/integration_tests/test_builtin_pow.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, f32, f64, c32 +from lpython import i32, i64, f32, f64, c32 def test_pow(): # TODO: the commented tests should also work @@ -80,7 +80,7 @@ def test_pow(): k: i64 k = i64(5) assert pow(i, j, k) == i64(4) - assert pow(102, 3, 121) == 38 + # assert pow(102, 3, 121) == 38 c1: c32 c1 = c32(complex(4, 5)) diff --git a/integration_tests/test_builtin_round.py b/integration_tests/test_builtin_round.py index 6ac3fd1d5e..ee158d18f3 100644 --- a/integration_tests/test_builtin_round.py +++ b/integration_tests/test_builtin_round.py @@ -1,4 +1,4 @@ -from ltypes import i8, i16, i32, i64, f32, f64 +from lpython import i8, i16, i32, i64, f32, f64 def test_round(): f: f64 diff --git a/integration_tests/test_builtin_str.py b/integration_tests/test_builtin_str.py index cb65a46b47..bf3c1c106f 100644 --- a/integration_tests/test_builtin_str.py +++ b/integration_tests/test_builtin_str.py @@ -1,4 +1,4 @@ -from ltypes import f32, f64, i32 +from lpython import f32, f64, i32 def test_str_int_float(): s: str diff --git a/integration_tests/test_builtin_str_02.py b/integration_tests/test_builtin_str_02.py index 6498a631b7..aef019b4bb 100644 --- a/integration_tests/test_builtin_str_02.py +++ b/integration_tests/test_builtin_str_02.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def _lpython_strcmp_eq(a: str, b: str) -> bool: if len(a) != len(b): diff --git a/integration_tests/test_builtin_sum.py b/integration_tests/test_builtin_sum.py new file mode 100644 index 0000000000..000198dad0 --- /dev/null +++ b/integration_tests/test_builtin_sum.py @@ -0,0 +1,28 @@ +from lpython import f32, f64, i32, i64 + +def test_sum(): + arr_i32 :list[i32] + arr_i32 = [6, 12] + res_i32 :i32 = sum(arr_i32) + assert res_i32 == 18 + + arr_i64 :list[i64] = [i64(600000000000), i64(1200000000000)] + res_i64 :i64 = sum(arr_i64) + assert res_i64 == i64(1800000000000) + + eps1 :f32 = f32(1e-12) + x :f32 = f32(12.5) + y :f32 = f32(6.5) + arr_f32 :list[f32] + arr_f32 = [x, y] + res_f32 :f32 = sum(arr_f32) + assert abs(res_f32 - f32(19.0)) < eps1 + + eps2: f64 = 1e-12 + arr_f64: list[f64] + arr_f64 = [12.6, 6.4] + res_f64 :f64 = sum(arr_f64) + assert abs(res_f64 - 19.0) < eps2 + + +test_sum() diff --git a/integration_tests/test_builtin_type.py b/integration_tests/test_builtin_type.py new file mode 100644 index 0000000000..188313444f --- /dev/null +++ b/integration_tests/test_builtin_type.py @@ -0,0 +1,32 @@ +from lpython import i32, f64 + +def test_builtin_type(): + i: i32 = 42 + f: f64 = 64.0 + s: str = "Hello, LPython!" + l: list[i32] = [1, 2, 3, 4, 5] + d: dict[str, i32] = {"a": 1, "b": 2, "c": 3} + t: tuple[str, i32] = ("a", 1) + res: str = "" + + res = str(type(i)) + print(res) + assert res == "" + res = str(type(f)) + print(res) + assert res == "" + res = str(type(s)) + print(res) + assert res == "" + res = str(type(l)) + print(res) + assert res == "" + res = str(type(d)) + print(res) + assert res == "" + res = str(type(t)) + print(res) + assert res == "" + + +test_builtin_type() diff --git a/integration_tests/test_builtin_type_set.py b/integration_tests/test_builtin_type_set.py new file mode 100644 index 0000000000..d0265b1c1a --- /dev/null +++ b/integration_tests/test_builtin_type_set.py @@ -0,0 +1,11 @@ +from lpython import i32 + +def test_builtin_type_set(): + st: set[i32] = {1, 2, 3, 4} + + res: str = str(type(st)) + print(res) + assert res == "" + + +test_builtin_type_set() diff --git a/integration_tests/test_c_interop_01.py b/integration_tests/test_c_interop_01.py index 3d8c5e7852..278e49a7ea 100644 --- a/integration_tests/test_c_interop_01.py +++ b/integration_tests/test_c_interop_01.py @@ -1,4 +1,4 @@ -from ltypes import ccall, f32, f64, i32, i64 +from lpython import ccall, f32, f64, i32, i64 #from math import pi @ccall @@ -9,14 +9,6 @@ def _lfortran_dsin(x: f64) -> f64: def _lfortran_ssin(x: f32) -> f32: pass -@ccall -def _lfortran_bgt32(i: i32, j: i32) -> i32: - pass - -@ccall -def _lfortran_bgt64(i: i64, j: i64) -> i32: - pass - #@ccall #def _lfortran_random_number(n: i64, v: f64[:]): # pass @@ -24,13 +16,8 @@ def _lfortran_bgt64(i: i64, j: i64) -> i32: def test_c_callbacks(): pi: f64 = 3.141592653589793238462643383279502884197 assert abs(_lfortran_dsin(pi) - 0.0) < 1e-12 - assert abs(_lfortran_dsin(pi/2) - 1.0) < 1e-12 + assert abs(_lfortran_dsin(pi/2.0) - 1.0) < 1e-12 assert abs(_lfortran_ssin(f32(pi)) - f32(0.0)) < f32(1e-6) assert abs(_lfortran_ssin(f32(pi/2.0)) - f32(1.0)) < f32(1e-6) - assert _lfortran_bgt32(3, 4) == 0 - assert _lfortran_bgt32(4, 3) == 1 - assert _lfortran_bgt64(i64(3), i64(4)) == 0 - assert _lfortran_bgt64(i64(4), i64(3)) == 1 - test_c_callbacks() diff --git a/integration_tests/test_c_interop_02.py b/integration_tests/test_c_interop_02.py index 55efd59e1d..1500e09892 100644 --- a/integration_tests/test_c_interop_02.py +++ b/integration_tests/test_c_interop_02.py @@ -1,4 +1,4 @@ -from ltypes import ccall, f32, f64, i8, i16, i32, i64 +from lpython import ccall, f32, f64, i8, i16, i32, i64 @ccall def f_f64_f64(x: f64) -> f64: diff --git a/integration_tests/test_c_interop_03.py b/integration_tests/test_c_interop_03.py index c94037a4d4..516eee6cda 100644 --- a/integration_tests/test_c_interop_03.py +++ b/integration_tests/test_c_interop_03.py @@ -1,4 +1,4 @@ -from ltypes import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, +from lpython import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer, empty_c_void_p) @ccall diff --git a/integration_tests/test_c_interop_04.py b/integration_tests/test_c_interop_04.py index 30bb8236b6..0be53d4841 100644 --- a/integration_tests/test_c_interop_04.py +++ b/integration_tests/test_c_interop_04.py @@ -1,4 +1,4 @@ -from ltypes import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, +from lpython import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer, empty_c_void_p) from numpy import empty, int32 diff --git a/integration_tests/test_c_interop_05.py b/integration_tests/test_c_interop_05.py index 116779d8db..aaa799520d 100644 --- a/integration_tests/test_c_interop_05.py +++ b/integration_tests/test_c_interop_05.py @@ -1,4 +1,4 @@ -from ltypes import ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer +from lpython import ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer, ccallback @ccall def f_i32_i32(x: i32) -> i32: diff --git a/integration_tests/test_cmath.py b/integration_tests/test_cmath.py index 2721b04dfa..5b8429f41c 100644 --- a/integration_tests/test_cmath.py +++ b/integration_tests/test_cmath.py @@ -1,6 +1,8 @@ -from cmath import (exp, log, sqrt, acos, asin, atan, cos, sin, tan, - acosh, asinh, atanh, cosh, sinh, tanh) -from ltypes import c64, c32 +from cmath import (acos, acosh, asin, asinh, atan, atanh, cos, cosh, exp, log, + phase, polar, rect, sin, sinh, sqrt, tan, tanh) + +from lpython import c32, c64, f64 + def test_power_logarithmic(): x: c64 @@ -59,6 +61,17 @@ def test_hyperbolic(): b = tanh(a) +def test_polar(): + x: c64 + eps: f64 + eps = 1e-12 + x = complex(1, -2) + assert f64(abs(f64(phase(x)) - (-1.1071487177940904))) < eps + assert f64(abs(f64(polar(x)[0]) - (2.23606797749979))) < eps + assert abs(abs(rect(2.23606797749979, -1.1071487177940904))-abs(x)) < eps + + test_power_logarithmic() test_trigonometric() test_hyperbolic() +test_polar() diff --git a/integration_tests/test_complex.py b/integration_tests/test_complex.py deleted file mode 100644 index dc9f4d230a..0000000000 --- a/integration_tests/test_complex.py +++ /dev/null @@ -1,142 +0,0 @@ -from ltypes import i32, i64, f32, f64, c32, c64 - -def test_real_imag(): - x: c64 - x = c64(2) + 3j - a: f64 - b: f64 - eps: f64 - eps = 1e-12 - a = x.real - b = x.imag - assert abs(a - 2.0) < eps - assert abs(b - 3.0) < eps - -def test_complex(): - x: c64 - x = complex(4.5, 6.7) - eps: f64 - eps = 1e-12 - assert abs(x.real - 4.5) < eps - assert abs(x.imag - 6.7) < eps - - x = complex(-4, 2) - assert abs(x.real - (-4.0)) < eps - assert abs(x.imag - 2.0) < eps - - x = complex(4, 7.89) - assert abs(x.real - 4.0) < eps - assert abs(x.imag - 7.89) < eps - - x = complex(5.6, 0) - assert abs(x.real - 5.6) < eps - assert abs(x.imag - 0.0) < eps - - a: f64 - a = 534.6 - x = complex(a, -a) # (f64, f64) - - assert abs(x.real - 534.60000000000002274) < eps - assert abs(x.imag - (-534.60000000000002274)) < eps - - a2: f32 - a2 = -f32(423.5430806348152437) - a3: f32 - a3 = f32(34.5) - x2: c32 - x2 = c32(complex(a2, a3)) # (f32, f32) - - assert f64(abs(x2.imag - f32(34.5))) < eps - - i1: i32 - i1 = -5 - i2: i64 - i2 = -i64(6) - - x = complex(a3, a) # (f32, f64) - x = complex(a, a3) # (f64, f32) - x = complex(i1, i2) # (i32, i64) - x = complex(i1, -i1) # (i32, i32) - x = complex(-i2, -i2) # (i64, i64) - x = complex(i2, -i1) # (i64, i32) - - -def test_complex_abs(): - x: c32 - x = c32(complex(3, 4)) - eps: f64 - eps = 1e-12 - assert f64(abs(f64(abs(x)) - 5.0)) < eps - y: c64 - y = complex(6, 8) - assert abs(abs(y) - 10.0) < eps - -def test_complex_binop_32(): - x: c32 - y: c32 - z: c32 - x = c32(c64(2) + 3j) - y = c32(c64(4) + 5j) - z = x + y - z = x - y - z = x * y - # TODO: - #z = x / y - z = x ** y - -def test_complex_binop_64(): - x: c64 - y: c64 - z: c64 - x = c64(2) + 3j - y = c64(4) + 5j - z = x + y - z = x - y - z = x * y - # TODO: - #z = x / y - z = x ** y - -def test_complex_unary_minus(): - c: c32 - c = c32(complex(3, 4.5)) - _c: c32 - _c = -c - assert abs(f64(_c.real) - (-3.0)) < 1e-12 - assert abs(f64(_c.imag) - (-4.5)) < 1e-12 - _c = c32(complex(5, -78)) - _c = -_c - assert abs(f64(_c.real) - (-5.0)) < 1e-12 - assert abs(f64(_c.imag) - 78.0) < 1e-12 - c2: c64 - c2 = complex(-4.5, -7.8) - c2 = -c2 - assert abs(c2.real - 4.5) < 1e-12 - assert abs(c2.imag - 7.8) < 1e-12 - c2 = c64(3) + 4j - c2 = -c2 - assert abs(c2.real - (-3.0)) < 1e-12 - assert abs(c2.imag - (-4.0)) < 1e-12 - -def test_complex_not(): - c: c32 - c = c32(complex(4, 5)) - b: bool - b = not c - assert not b - - c2: c64 - c2 = complex(0, 0) - b = not c2 - assert b - -def check(): - test_real_imag() - test_complex() - test_complex_abs() - test_complex_binop_32() - test_complex_binop_64() - test_complex_unary_minus() - test_complex_not() - -check() diff --git a/integration_tests/test_complex_01.py b/integration_tests/test_complex_01.py new file mode 100644 index 0000000000..04f88b6895 --- /dev/null +++ b/integration_tests/test_complex_01.py @@ -0,0 +1,102 @@ +from lpython import i32, i64, f32, f64, c32, c64 + +def test_real_imag(): + x: c64 + x = c64(2) + 3j + a: f64 + b: f64 + eps: f64 + eps = 1e-12 + a = x.real + b = x.imag + assert abs(a - 2.0) <= eps + assert abs(b - 3.0) <= eps + +def test_complex(): + x: c64 + x = complex(4.5, 6.7) + eps: f64 + eps = 1e-12 + assert abs(x.real - 4.5) <= eps + assert abs(x.imag - 6.7) <= eps + + x = complex(-4, 2) + assert abs(x.real - (-4.0)) <= eps + assert abs(x.imag - 2.0) <= eps + + x = complex(4, 7.89) + assert abs(x.real - 4.0) <= eps + assert abs(x.imag - 7.89) <= eps + + x = complex(5.6, 0) + assert abs(x.real - 5.6) <= eps + assert abs(x.imag - 0.0) <= eps + + a: f64 + a = 534.6 + x = complex(a, -a) # (f64, f64) + + assert abs(x.real - 534.60000000000002274) <= eps + assert abs(x.imag - (-534.60000000000002274)) <= eps + + a2: f32 + a2 = -f32(423.5430806348152437) + a3: f32 + a3 = f32(34.5) + x2: c32 + x2 = c32(complex(a2, a3)) # (f32, f32) + + assert f64(abs(x2.imag - f32(34.5))) <= eps + + i1: i32 + i1 = -5 + i2: i64 + i2 = -i64(6) + + x = complex(a3, a) # (f32, f64) + x = complex(a, a3) # (f64, f32) + x = complex(i1, i2) # (i32, i64) + x = complex(i1, -i1) # (i32, i32) + x = complex(-i2, -i2) # (i64, i64) + x = complex(i2, -i1) # (i64, i32) + +def test_complex_unary_minus(): + c: c32 + c = c32(complex(3, 4.5)) + _c: c32 + _c = -c + assert abs(f64(_c.real) - (-3.0)) <= 1e-12 + assert abs(f64(_c.imag) - (-4.5)) <= 1e-12 + _c = c32(complex(5, -78)) + _c = -_c + assert abs(f64(_c.real) - (-5.0)) <= 1e-12 + assert abs(f64(_c.imag) - 78.0) <= 1e-12 + c2: c64 + c2 = complex(-4.5, -7.8) + c2 = -c2 + assert abs(c2.real - 4.5) <= 1e-12 + assert abs(c2.imag - 7.8) <= 1e-12 + c2 = c64(3) + 4j + c2 = -c2 + assert abs(c2.real - (-3.0)) <= 1e-12 + assert abs(c2.imag - (-4.0)) <= 1e-12 + +def test_complex_not(): + c: c32 + c = c32(complex(4, 5)) + b: bool + b = not c + assert not b + + c2: c64 + c2 = complex(0, 0) + b = not c2 + assert b + +def check(): + test_real_imag() + test_complex() + test_complex_unary_minus() + test_complex_not() + +check() diff --git a/integration_tests/test_complex_02.py b/integration_tests/test_complex_02.py new file mode 100644 index 0000000000..9a48c6fcb9 --- /dev/null +++ b/integration_tests/test_complex_02.py @@ -0,0 +1,44 @@ +from lpython import f64, c32, c64 + +def test_complex_abs(): + x: c32 + x = c32(complex(3, 4)) + eps: f64 + eps = 1e-12 + assert f64(abs(f64(abs(x)) - 5.0)) < eps + y: c64 + y = complex(6, 8) + assert abs(abs(y) - 10.0) < eps + +def test_complex_binop_32(): + x: c32 + y: c32 + z: c32 + x = c32(c64(2) + 3j) + y = c32(c64(4) + 5j) + z = x + y + z = x - y + z = x * y + # TODO: + #z = x / y + z = x ** y + +def test_complex_binop_64(): + x: c64 + y: c64 + z: c64 + x = c64(2) + 3j + y = c64(4) + 5j + z = x + y + z = x - y + z = x * y + # TODO: + #z = x / y + z = x ** y + +def check(): + test_complex_abs() + test_complex_binop_32() + test_complex_binop_64() + +check() diff --git a/integration_tests/test_const_access.py b/integration_tests/test_const_access.py new file mode 100644 index 0000000000..4368e3ed0c --- /dev/null +++ b/integration_tests/test_const_access.py @@ -0,0 +1,9 @@ +from lpython import i32, Const + +CONST_LIST: Const[list[i32]] = [1, 2, 3, 4, 5] +CONST_DICTIONARY: Const[dict[str, i32]] = {"a": 1, "b": 2, "c": 3} + +assert CONST_LIST[0] == 1 +assert CONST_LIST[-2] == 4 + +assert CONST_DICTIONARY["a"] == 1 \ No newline at end of file diff --git a/integration_tests/test_const_dict.py b/integration_tests/test_const_dict.py new file mode 100644 index 0000000000..e06578fc45 --- /dev/null +++ b/integration_tests/test_const_dict.py @@ -0,0 +1,24 @@ +from lpython import i32, f64, Const + +CONST_DICTIONARY_INTEGR: Const[dict[str, i32]] = {"a": 1, "b": 2, "c": 3} + +print(CONST_DICTIONARY_INTEGR.get("a")) +assert CONST_DICTIONARY_INTEGR.get("a") == 1 + +print(CONST_DICTIONARY_INTEGR.keys()) +assert len(CONST_DICTIONARY_INTEGR.keys()) == 3 + +print(CONST_DICTIONARY_INTEGR.values()) +assert len(CONST_DICTIONARY_INTEGR.values()) == 3 + +CONST_DICTIONARY_FLOAT: Const[dict[str, f64]] = {"a": 1.0, "b": 2.0, "c": 3.0} + +print(CONST_DICTIONARY_FLOAT.get("a")) +assert CONST_DICTIONARY_FLOAT.get("a") == 1.0 + +print(CONST_DICTIONARY_FLOAT.keys()) +assert len(CONST_DICTIONARY_FLOAT.keys()) == 3 + +print(CONST_DICTIONARY_FLOAT.values()) +assert len(CONST_DICTIONARY_FLOAT.values()) == 3 + diff --git a/integration_tests/test_const_list.py b/integration_tests/test_const_list.py new file mode 100644 index 0000000000..4f0a568251 --- /dev/null +++ b/integration_tests/test_const_list.py @@ -0,0 +1,19 @@ +from lpython import i32, Const + + +def test_const_list(): + CONST_INTEGER_LIST: Const[list[i32]] = [1, 2, 3, 4, 5, 1] + + print(CONST_INTEGER_LIST.count(1)) + print(CONST_INTEGER_LIST.index(1)) + assert CONST_INTEGER_LIST.count(1) == 2 + assert CONST_INTEGER_LIST.index(1) == 0 + + CONST_STRING_LIST: Const[list[str]] = ["ALPHA", "BETA", "RELEASE"] + print(CONST_STRING_LIST.count("ALPHA")) + print(CONST_STRING_LIST.index("RELEASE")) + assert CONST_STRING_LIST.count("ALPHA") == 1 + assert CONST_STRING_LIST.index("RELEASE") == 2 + + +test_const_list() diff --git a/integration_tests/test_dict_01.py b/integration_tests/test_dict_01.py index 99b3043248..0be09ad2fb 100644 --- a/integration_tests/test_dict_01.py +++ b/integration_tests/test_dict_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def test_dict(): rollnumber2cpi: dict[i32, f64] = {} @@ -8,12 +8,20 @@ def test_dict(): rollnumber2cpi[0] = 1.1 for i in range(1000, 1000 + size): - rollnumber2cpi[i] = float(i/100.0 + 5.0) + rollnumber2cpi[i] = float(i)/100.0 + 5.0 for i in range(1000 + size - 1, 1001, -1): - assert abs(rollnumber2cpi[i] - i/100.0 - 5.0) <= 1e-12 + assert abs(rollnumber2cpi[i] - f64(i)/100.0 - 5.0) <= 1e-12 assert abs(rollnumber2cpi[0] - 1.1) <= 1e-12 assert len(rollnumber2cpi) == 1001 +def test_issue_1839(): + assert len({1: 2, 1: 3, 4: 5}) == 2 + x: dict[i32, i32] = {} + x = {1: 1, 1: 2, 1: 3} + assert len(x) == 1 + + test_dict() +test_issue_1839() diff --git a/integration_tests/test_dict_02.py b/integration_tests/test_dict_02.py index 2c397ae90c..672fcb1a5f 100644 --- a/integration_tests/test_dict_02.py +++ b/integration_tests/test_dict_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def test_dict(): rollnumber2cpi: dict[i32, f64] = {0: 1.1} diff --git a/integration_tests/test_dict_03.py b/integration_tests/test_dict_03.py index fa9ecc4691..24583d4ba8 100644 --- a/integration_tests/test_dict_03.py +++ b/integration_tests/test_dict_03.py @@ -1,4 +1,4 @@ -from ltypes import f64, i32, i64 +from lpython import f64, i32, i64 def power2(i: i64, mod: i64) -> i64: if i == i64(0) or i == i64(1): diff --git a/integration_tests/test_dict_04.py b/integration_tests/test_dict_04.py index ae6a4ec919..2665f38c11 100644 --- a/integration_tests/test_dict_04.py +++ b/integration_tests/test_dict_04.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64, f64 +from lpython import i32, i64, f64 from math import pi, sin, cos def test_dict(): diff --git a/integration_tests/test_dict_05.py b/integration_tests/test_dict_05.py index 68d93705e6..df35e97494 100644 --- a/integration_tests/test_dict_05.py +++ b/integration_tests/test_dict_05.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def test_dict(): rollnumber2cpi: dict[i32, f64] = {} @@ -7,7 +7,7 @@ def test_dict(): end: i32 = 501 for i in range(start, end): - rollnumber2cpi[i] = float(i/100.0 + 5.0) + rollnumber2cpi[i] = float(i)/100.0 + 5.0 # for i in range(end - 1, start + 1, -1): # assert abs(rollnumber2cpi[i] - i/100.0 - 5.0) <= 1e-12 diff --git a/integration_tests/test_dict_06.py b/integration_tests/test_dict_06.py new file mode 100644 index 0000000000..44ba650bfa --- /dev/null +++ b/integration_tests/test_dict_06.py @@ -0,0 +1,24 @@ +from lpython import f64, i32 + +def fill_rollnumber2cpi(size: i32) -> dict[i32, f64]: + i : i32 + rollnumber2cpi: dict[i32, f64] = {} + + rollnumber2cpi[0] = 1.1 + for i in range(1000, 1000 + size): + rollnumber2cpi[i] = float(i)/100.0 + 5.0 + + return rollnumber2cpi + +def test_dict(): + i: i32 + size: i32 = 200 + rollnumber2cpi: dict[i32, f64] = fill_rollnumber2cpi(size) + + for i in range(1000 + size - 1, 1001, -1): + assert abs(rollnumber2cpi[i] - f64(i)/100.0 - 5.0) <= 1e-12 + + assert abs(rollnumber2cpi[0] - 1.1) <= 1e-12 + assert len(rollnumber2cpi) == 201 + +test_dict() diff --git a/integration_tests/test_dict_07.py b/integration_tests/test_dict_07.py new file mode 100644 index 0000000000..8c6b6e54a1 --- /dev/null +++ b/integration_tests/test_dict_07.py @@ -0,0 +1,21 @@ +from lpython import i32 + + +def fill_smalltocapital() -> dict[str, str]: + return {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D','e': 'E', + 'f': 'F', 'g': 'G', 'h': 'H', 'i': 'I','j': 'J', + 'k': 'K', 'l': 'L', 'm': 'M', 'n': 'N','o': 'O', + 'p': 'P', 'q': 'Q', 'r': 'R', 's': 'S','t': 'T', + 'u': 'U', 'v': 'V', 'w': 'W', 'x': 'X','y': 'Y', + 'z': 'Z'} + +def test_dict(): + i: i32 + smalltocaps: dict[str, str] + smalltocaps = fill_smalltocapital() + + assert len(smalltocaps) == 26 + for i in range(97, 97 + 26): + assert smalltocaps[chr(i)] == chr(i - 32) + +test_dict() diff --git a/integration_tests/test_dict_08.py b/integration_tests/test_dict_08.py new file mode 100644 index 0000000000..1845849458 --- /dev/null +++ b/integration_tests/test_dict_08.py @@ -0,0 +1,31 @@ +# test case for passing dict as args and return value to a function + +from lpython import i32 + +def get_cubes_from_squares(squares: dict[i32, i32]) -> dict[i32, i32]: + i : i32 + cubes: dict[i32, i32] = {} + for i in range(1, 16): + cubes[i] = squares[i] * i + return cubes + +def assert_dict(squares: dict[i32, i32], cubes: dict[i32, i32]): + i : i32 + for i in range(1, 16): + assert squares[i] == (i * i) + for i in range(1, 16): + assert cubes[i] == (i * i * i) + assert len(squares) == 15 + assert len(cubes) == 15 + +def test_dict(): + squares : dict[i32, i32] + squares = {1:1, 2:4, 3:9, 4:16, 5:25, 6:36, 7:49, + 8:64, 9:81, 10:100, 11:121, 12:144, 13:169, + 14: 196, 15:225} + + cubes : dict[i32, i32] + cubes = get_cubes_from_squares(squares) + assert_dict(squares, cubes) + +test_dict() diff --git a/integration_tests/test_dict_09.py b/integration_tests/test_dict_09.py new file mode 100644 index 0000000000..948288c0d3 --- /dev/null +++ b/integration_tests/test_dict_09.py @@ -0,0 +1,29 @@ +# test case for passing dict as args and return value to a function + +from lpython import f64, i32 + +def fill_rollnumber2cpi(size: i32) -> dict[i32, f64]: + i : i32 + rollnumber2cpi: dict[i32, f64] = {} + + rollnumber2cpi[0] = 1.1 + for i in range(1000, 1000 + size): + rollnumber2cpi[i] = float(i)/100.0 + 5.0 + + return rollnumber2cpi + +def test_assertion(rollnumber2cpi: dict[i32, f64], size: i32): + i: i32 + for i in range(1000 + size - 1, 1001, -1): + assert abs(rollnumber2cpi[i] - f64(i)/100.0 - 5.0) <= 1e-12 + + assert abs(rollnumber2cpi[0] - 1.1) <= 1e-12 + assert len(rollnumber2cpi) == 201 + +def test_dict(): + size: i32 = 200 + rollnumber2cpi: dict[i32, f64] = fill_rollnumber2cpi(size) + + test_assertion(rollnumber2cpi, size) + +test_dict() diff --git a/integration_tests/test_dict_10.py b/integration_tests/test_dict_10.py new file mode 100644 index 0000000000..8adbeab2ac --- /dev/null +++ b/integration_tests/test_dict_10.py @@ -0,0 +1,22 @@ +from lpython import i32 + +# test case for passing dict with key-value as strings as argument to function + +def test_assertion(smalltocaps: dict[str, str]): + i: i32 + assert len(smalltocaps) == 26 + for i in range(97, 97 + 26): + assert smalltocaps[chr(i)] == chr(i - 32) + +def test_dict(): + smalltocaps: dict[str, str] + smalltocaps = {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D','e': 'E', + 'f': 'F', 'g': 'G', 'h': 'H', 'i': 'I','j': 'J', + 'k': 'K', 'l': 'L', 'm': 'M', 'n': 'N','o': 'O', + 'p': 'P', 'q': 'Q', 'r': 'R', 's': 'S','t': 'T', + 'u': 'U', 'v': 'V', 'w': 'W', 'x': 'X','y': 'Y', + 'z': 'Z'} + + test_assertion(smalltocaps) + +test_dict() diff --git a/integration_tests/test_dict_11.py b/integration_tests/test_dict_11.py new file mode 100644 index 0000000000..57c64fe1b8 --- /dev/null +++ b/integration_tests/test_dict_11.py @@ -0,0 +1,16 @@ +from lpython import i32 + +def test_dict_11(): + num : dict[i32, i32] + num = {11: 22, 33: 44, 55: 66} + assert num.get(7, -1) == -1 + assert num.get(11, -1) == 22 + assert num.get(33, -1) == 44 + assert num.get(55, -1) == 66 + assert num.get(72, -110) == -110 + d : dict[i32, str] + d = {1: "1", 2: "22", 3: "333"} + assert d.get(2, "00") == "22" + assert d.get(21, "nokey") == "nokey" + +test_dict_11() diff --git a/integration_tests/test_dict_12.py b/integration_tests/test_dict_12.py new file mode 100644 index 0000000000..e56ac43f32 --- /dev/null +++ b/integration_tests/test_dict_12.py @@ -0,0 +1,36 @@ +from lpython import i32 + +def main(): + d: dict[str, i32] = { + '2': 2, '3': 3, + '4': 4, '5': 5, '6': 6, '7': 7, + '8': 8, '9': 9, + 'a': 10, 'b': 11, 'c': 12, 'd': 13, + 'A': 100, 'B': 110, 'C': 120, 'D': 130, + 'e': 14, 'f': 15, + 'E': 140, 'F': 150} + + assert (d['2'] == 2) + assert (d['3'] == 3) + assert (d['4'] == 4) + assert (d['5'] == 5) + assert (d['6'] == 6) + assert (d['7'] == 7) + assert (d['8'] == 8) + assert (d['9'] == 9) + + assert (d['a'] == 10) + assert (d['b'] == 11) + assert (d['c'] == 12) + assert (d['d'] == 13) + assert (d['A'] == 100) + assert (d['B'] == 110) + assert (d['C'] == 120) + assert (d['D'] == 130) + + assert (d['e'] == 14) + assert (d['f'] == 15) + assert (d['E'] == 140) + assert (d['F'] == 150) + +main() diff --git a/integration_tests/test_dict_13.py b/integration_tests/test_dict_13.py new file mode 100644 index 0000000000..670a9eb60c --- /dev/null +++ b/integration_tests/test_dict_13.py @@ -0,0 +1,43 @@ +from lpython import i32 + +I4C: dict[str, i32] = { + '0': 0, '1': 1, '2': 2, '3': 3, + '4': 4, '5': 5, '6': 6, '7': 7, + '8': 8, '9': 9, + 'a': 10, 'b': 11, 'c': 12, 'd': 13, + 'A': 10, 'B': 11, 'C': 12, 'D': 13, + 'e': 14, 'f': 15, + 'E': 14, 'F': 15} + + +def cnvi(s : str, base : i32=10) -> i32: + """Assume input has been through 'match_integer'.""" + assert base == 10 or base == 8 or base == 16 or base == 2 + result : i32 = 0 + c : str + pow_: i32 = base ** (len(s) - 1) + for c in s: + incr : i32 = pow_ * I4C[c] + result += incr + pow_ = (pow_ // base) + return result + + +if __name__ == '__main__': + print(cnvi('0b0', base=2)) + assert cnvi('0b0', base=2) == 22 + + print(cnvi('0b1', base=2)) + assert cnvi('0b1', base=2) == 23 + + print(cnvi('0b10', base=2)) + assert cnvi('0b10', base=2) == 46 + + print(cnvi('0b11', base=2)) + assert cnvi('0b11', base=2) == 47 + + print(cnvi('0b11110100111', base=2)) + assert cnvi('0b11110100111', base=2) == 24487 + + print(cnvi('0b7a7', base=16)) + assert cnvi('0b7a7', base=16) == 47015 diff --git a/integration_tests/test_dict_14.py b/integration_tests/test_dict_14.py new file mode 100644 index 0000000000..4fe91c687f --- /dev/null +++ b/integration_tests/test_dict_14.py @@ -0,0 +1,65 @@ +from lpython import i32 + +def test_dict(): + d_i32: dict[i32, i32] = {5: 1, 5: 2} + d_str: dict[str, i32] = {'a': 1, 'a': 2} + l_str_1: list[str] = [] + l_str_2: list[str] = [] + l_i32_1: list[i32] = [] + l_i32_2: list[i32] = [] + i: i32 + s: str + + assert len(d_i32) == 1 + d_i32.pop(5) + assert len(d_i32) == 0 + + assert len(d_str) == 1 + d_str.pop('a') + assert len(d_str) == 0 + + d_str = {'a': 2, 'a': 2, 'b': 2, 'c': 3, 'a': 5} + assert len(d_str) == 3 + d_str.pop('a') + assert len(d_str) == 2 + d_str.pop('b') + assert len(d_str) == 1 + + d_str['a'] = 20 + assert len(d_str) == 2 + d_str.pop('c') + assert len(d_str) == 1 + + l_str_1 = d_str.keys() + for s in l_str_1: + l_str_2.append(s) + assert l_str_2 == ['a'] + l_i32_1 = d_str.values() + for i in l_i32_1: + l_i32_2.append(i) + assert l_i32_2 == [20] + + d_i32 = {5: 2, 5: 2, 6: 2, 7: 3, 5: 5} + assert len(d_i32) == 3 + d_i32.pop(5) + assert len(d_i32) == 2 + d_i32.pop(6) + assert len(d_i32) == 1 + + d_i32[6] = 30 + assert len(d_i32) == 2 + d_i32.pop(7) + assert len(d_i32) == 1 + + l_i32_1 = d_i32.keys() + l_i32_2.clear() + for i in l_i32_1: + l_i32_2.append(i) + assert l_i32_2 == [6] + l_i32_1 = d_i32.values() + l_i32_2.clear() + for i in l_i32_1: + l_i32_2.append(i) + assert l_i32_2 == [30] + +test_dict() diff --git a/integration_tests/test_dict_bool.py b/integration_tests/test_dict_bool.py new file mode 100644 index 0000000000..c1e4e9cca9 --- /dev/null +++ b/integration_tests/test_dict_bool.py @@ -0,0 +1,47 @@ +from lpython import i32, f64 + +def test_dict_bool(): + d_int: dict[bool, i32] = {} + d_float: dict[bool, f64] = {} + d_str: dict[bool, str] = {} + i: i32 + j: f64 + s: str = "" + l_str: list[str] = ["a", "b", "c", "d"] + + for i in range(10): + d_int[True] = i + assert d_int[True] == i + + for i in range(10, 20): + d_int[True] = i + d_int[False] = i + 1 + assert d_int[True] == d_int[False] - 1 + assert d_int[True] == i + + d_int[True] = 0 + d_int[False] = d_int[True] + + for i in range(10, 99): + d_int[i%2 == 0] = d_int[i%2 == 0] + 1 + assert d_int[True] == d_int[False] + 1 + assert d_int[True] == 45 + + j = 0.0 + while j < 1.0: + d_float[False] = j + 1.0 + d_float[True] = d_float[False] * d_float[False] + assert d_float[True] == (j + 1.0) * (j + 1.0) + assert d_float[False] == j + 1.0 + j = j + 0.1 + + d_str[False] = s + + for i in range(len(l_str)): + d_str[True] = d_str[False] + s += l_str[i] + d_str[False] = s + assert d_str[True] + l_str[i] == d_str[False] + assert d_str[False] == s + +test_dict_bool() diff --git a/integration_tests/test_dict_clear.py b/integration_tests/test_dict_clear.py new file mode 100644 index 0000000000..eccfea0aa6 --- /dev/null +++ b/integration_tests/test_dict_clear.py @@ -0,0 +1,18 @@ +def test_clear(): + a: dict[i32, i32] = {1:1, 2:2} + + a.clear() + a[3] = 3 + + assert len(a) == 1 + assert 3 in a + + b: dict[str, str] = {'a':'a', 'b':'b'} + + b.clear() + b['c'] = 'c' + + assert len(b) == 1 + assert 'c' in b + +test_clear() diff --git a/integration_tests/test_dict_increment.py b/integration_tests/test_dict_increment.py new file mode 100644 index 0000000000..b342e26bcf --- /dev/null +++ b/integration_tests/test_dict_increment.py @@ -0,0 +1,66 @@ +from lpython import i32, f64 + +def test_dict_increment(): + d_int_int: dict[i32, i32] + d_int_float: dict[i32, f64] + d_bool_float: dict[bool, f64] + d_str_float: dict[str, f64] + d_int_str: dict[i32, str] + i1: i32 + i2: i32 + j1: f64 + j2: f64 + s1: str + + d_int_int = {0: 1} + d_int_int[0] += 1000 + assert d_int_int[0] == 1001 + + i2 = 1 + d_int_int = {1: i2} + for i1 in range(10): + d_int_int[1] += i1 + i2 += i1 + assert d_int_int[1] == i2 + + i2 = 10 + d_int_int = {0: 0, 1: 0} + for i1 in range(i2): + d_int_int[i1 % 2] += 1 + assert d_int_int[0] == d_int_int[1] + assert d_int_int[0] == i2 // 2 + + j1 = 2.0 + d_int_float = {2: j1} + while j1 < 4.0: + d_int_float[2] += 0.1 + j1 += 0.1 + assert d_int_float[2] == j1 + + j1 = 0.0 + j2 = 0.0 + d_bool_float = {True: 0.0, False: 0.0} + while j1 < 4.0: + d_bool_float[j1 < 2.0] += 0.1 + if j1 < 2.0: + j2 += 0.1 + j1 += 0.1 + assert d_bool_float[j1 < 2.0] == d_bool_float[j1 > 2.0] + assert d_bool_float[True] == j2 + + j1 = 2.0 + d_str_float = {'key': j1} + s1 = "ke" + while j1 < 4.0: + d_str_float[s1 + 'y'] += 0.1 + j1 += 0.1 + assert d_str_float['key'] == j1 + + s1 = "0" + d_int_str = {-1: s1} + for i1 in range(10): + d_int_str[-1] += str(i1) + s1 += str(i1) + assert d_int_str[-1] == s1 + +test_dict_increment() diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py new file mode 100644 index 0000000000..2bcc20c084 --- /dev/null +++ b/integration_tests/test_dict_keys_values.py @@ -0,0 +1,99 @@ +from lpython import i32, f64 + +def test_dict_keys_values(): + d1: dict[i32, i32] = {} + k1: list[i32] + k1_copy: list[i32] = [] + v1: list[i32] + v1_copy: list[i32] = [] + i: i32 + j: i32 + s: str + key_count: i32 + + for i in range(105, 115): + d1[i] = i + 1 + k1 = d1.keys() + for i in k1: + k1_copy.append(i) + v1 = d1.values() + for i in v1: + v1_copy.append(i) + assert len(k1) == 10 + for i in range(105, 115): + key_count = 0 + for j in range(len(k1)): + if k1_copy[j] == i: + key_count += 1 + assert v1_copy[j] == d1[i] + assert key_count == 1 + + d2: dict[str, str] = {} + k2: list[str] + k2_copy: list[str] = [] + v2: list[str] + v2_copy: list[str] = [] + + for i in range(105, 115): + d2[str(i)] = str(i + 1) + k2 = d2.keys() + for s in k2: + k2_copy.append(s) + v2 = d2.values() + for s in v2: + v2_copy.append(s) + assert len(k2) == 10 + for i in range(105, 115): + key_count = 0 + for j in range(len(k2)): + if k2_copy[j] == str(i): + key_count += 1 + assert v2_copy[j] == d2[str(i)] + assert key_count == 1 + + + # dict.keys on dict constant + print({1: "a"}.keys()) + assert len({1: "a"}.keys()) == 1 + + print({"a": 1, "b": 2, "c": 3}.keys()) + assert len({"a": 1, "b": 2, "c": 3}.keys()) == 3 + + print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) == 3 + + print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) == 3 + + k_1: list[str] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.keys() + print(k_1) + assert len(k_1) == 3 + + k_2: list[tuple[i32, i32]] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys() + print(k_2) + assert len(k_2) == 3 + + + # dict.values on dict constant + print({1: "a"}.values()) + assert len({1: "a"}.values()) == 1 + + print({"a": 1, "b": 2, "c": 3}.values()) + assert len({"a": 1, "b": 2, "c": 3}.values()) == 3 + + print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) == 3 + + print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) == 3 + + v_1: list[list[i32]] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.values() + print(v_1) + assert len(v_1) == 3 + + v_2: list[str] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values() + print(v_2) + assert len(v_2) == 3 + + +test_dict_keys_values() diff --git a/integration_tests/test_dict_nested1.py b/integration_tests/test_dict_nested1.py new file mode 100644 index 0000000000..14de899610 --- /dev/null +++ b/integration_tests/test_dict_nested1.py @@ -0,0 +1,9 @@ +from lpython import i32 + +def test_nested_dict(): + d: dict[i32, dict[i32, i32]] = {1001: {2002: 3003}, 1002: {101: 2}} + d[1001] = d[1002] + d[1001][100] = 4005 + assert d[1001][100] == 4005 + +test_nested_dict() diff --git a/integration_tests/test_for_loop.py b/integration_tests/test_for_loop.py index c94161f080..3f66e992c4 100644 --- a/integration_tests/test_for_loop.py +++ b/integration_tests/test_for_loop.py @@ -1,3 +1,5 @@ +from lpython import i32 + def test_issue_1153(): start: list[i32] = [-10, 0, 10] stop: list[i32] = [20, 0, -20] diff --git a/integration_tests/test_generics_01.py b/integration_tests/test_generics_01.py index e6074541be..871f8b48ac 100644 --- a/integration_tests/test_generics_01.py +++ b/integration_tests/test_generics_01.py @@ -1,5 +1,5 @@ from overload_testing import foo, test -from ltypes import overload, i32, i64 +from lpython import overload, i32, i64 import overload_testing2 diff --git a/integration_tests/test_global_decl.py b/integration_tests/test_global_decl.py index beb67fc441..d256f37d15 100644 --- a/integration_tests/test_global_decl.py +++ b/integration_tests/test_global_decl.py @@ -1,9 +1,9 @@ -from ltypes import i32 +from lpython import i32, Const from numpy import empty, int32 # issue-1368 -SIZE: i32 = i32(3) +SIZE: Const[i32] = i32(3) def main() -> None: xs: i32[SIZE] = empty(SIZE, dtype=int32) diff --git a/integration_tests/test_global_set.py b/integration_tests/test_global_set.py new file mode 100644 index 0000000000..487f12d108 --- /dev/null +++ b/integration_tests/test_global_set.py @@ -0,0 +1,9 @@ +from lpython import i32 + +s1: set[str] = {"a", "b", "c", "a"} +s2: set[i32] = {1, 2, 3, 1} +s3: set[tuple[i32, i32]] = {(1, 2), (2, 3), (4, 5)} + +assert len(s1) == 3 +assert len(s2) == 3 +assert len(s3) == 3 diff --git a/integration_tests/test_gruntz.py b/integration_tests/test_gruntz.py new file mode 100644 index 0000000000..70b5a307ee --- /dev/null +++ b/integration_tests/test_gruntz.py @@ -0,0 +1,80 @@ +from lpython import S +from sympy import Symbol, log, E, Pow, exp + +def mmrv(e: S, x: S) -> list[S]: + empty_list : list[S] = [] + if not e.has(x): + return empty_list + elif e == x: + list1: list[S] = [x] + return list1 + elif e.func == log: + arg0: S = e.args[0] + list2: list[S] = mmrv(arg0, x) + return list2 + elif e.func == Pow: + base: S = e.args[0] + exponent: S = e.args[1] + one: S = S(1) + if base != E: + newe_exponent: S = S(1) + newe: S = e + while newe.func == Pow: + newe_base: S = newe.args[0] + newe_args1: S = newe.args[1] + newe_exponent = newe_exponent * newe_args1 + newe = newe_base + if newe_base == one: + return empty_list + if not newe_exponent.has(x): + list3: list[S] = mmrv(newe_base, x) + return list3 + else: + # TODO as noted in #2526 + pass + else: + if exponent.func == log: + list4: list[S] = mmrv(exponent.args[0], x) + return list4 + # TODO + pass + else: + raise + +def test_mrv(): + # Case 1 + x: S = Symbol("x") + y: S = Symbol("y") + ans1: list[S] = mmrv(y, x) + print(ans1) + assert len(ans1) == 0 + + # Case 2 + ans2: list[S] = mmrv(x, x) + ele1: S = ans2[0] + print(ele1) + assert ele1 == x + assert len(ans2) == 1 + + # Case 3 + ans3: list[S] = mmrv(log(x), x) + ele2: S = ans3[0] + print(ele2) + assert ele2 == x + assert len(ans3) == 1 + + # Case 4 + ans4: list[S] = mmrv(x**S(2), x) + ele3: S = ans4[0] + print(ele3) + assert ele3 == x + assert len(ans4) == 1 + + # Case 5 + ans5: list[S] = mmrv(exp(log(x)), x) + ele4: S = ans5[0] + print(ele4) + assert ele4 == x + assert len(ans5) == 1 + +test_mrv() \ No newline at end of file diff --git a/integration_tests/test_ifexp.py b/integration_tests/test_ifexp.py deleted file mode 100644 index 3b10e39326..0000000000 --- a/integration_tests/test_ifexp.py +++ /dev/null @@ -1,11 +0,0 @@ -from ltypes import i32, f32 - -def f(): - i: i32 - i = 1 if True else 0 - assert i == 1 - j: f32 - j = f32(1.0 if 1.0 <= 0.0 else 0.0) - assert j == f32(0.0) - -f() diff --git a/integration_tests/test_ifexp_01.py b/integration_tests/test_ifexp_01.py new file mode 100644 index 0000000000..fb2c0e06b3 --- /dev/null +++ b/integration_tests/test_ifexp_01.py @@ -0,0 +1,14 @@ +from lpython import i32, f32 + +def f(): + i: i32 + i = 1 if True else 0 + print (i) + assert i == 1 + + j: f32 + j = f32(1.0 if 1.0 <= 0.0 else 0.0) + print(j) + assert j == f32(0.0) + +f() diff --git a/integration_tests/test_ifexp_02.py b/integration_tests/test_ifexp_02.py new file mode 100644 index 0000000000..5a41259476 --- /dev/null +++ b/integration_tests/test_ifexp_02.py @@ -0,0 +1,17 @@ +from lpython import i32 + +def g() -> i32: + return 10 + +def f(): + i: i32 + j: i32 + k: i32 + i = 5 + j = 6 + k = g() if i > j else g() - 1 + + print(k) + assert k == 9 + +f() diff --git a/integration_tests/test_ifexp_03.py b/integration_tests/test_ifexp_03.py new file mode 100644 index 0000000000..21c0424ac9 --- /dev/null +++ b/integration_tests/test_ifexp_03.py @@ -0,0 +1,11 @@ +from lpython import i32 + +def fib(n: i32) -> i32: + return fib(n - 1) + fib(n - 2) if n >= 3 else 1 + +def main0(): + res: i32 = fib(30) + print(res) + assert res == 832040 + +main0() diff --git a/integration_tests/test_import/import_module_01/test_import_4.py b/integration_tests/test_import/import_module_01/test_import_4.py index 7f0c7ac5c1..f85a664a12 100644 --- a/integration_tests/test_import/import_module_01/test_import_4.py +++ b/integration_tests/test_import/import_module_01/test_import_4.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, Const +from lpython import i32, f64, Const e: Const[f64] = 2.71828182845904523536 diff --git a/integration_tests/test_import/import_module_02/test_import_3.py b/integration_tests/test_import/import_module_02/test_import_3.py index 28bfbb7f0f..015ac2ae3f 100644 --- a/integration_tests/test_import/import_module_02/test_import_3.py +++ b/integration_tests/test_import/import_module_02/test_import_3.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, Const +from lpython import i32, f64, Const μ: Const[f64] = 1.45136923488338105028 diff --git a/integration_tests/test_import/sys.py b/integration_tests/test_import/sys.py new file mode 100644 index 0000000000..ac905eb29d --- /dev/null +++ b/integration_tests/test_import/sys.py @@ -0,0 +1,5 @@ +from lpython import i32 + +def hi_from_user_sys() -> i32: + print("hi from user sys!") + return -5 diff --git a/integration_tests/test_import_05.py b/integration_tests/test_import_05.py new file mode 100644 index 0000000000..8ee6c54c7a --- /dev/null +++ b/integration_tests/test_import_05.py @@ -0,0 +1,3 @@ +from test_import.sys import hi_from_user_sys + +assert hi_from_user_sys() == -5 diff --git a/integration_tests/test_import_06.py b/integration_tests/test_import_06.py new file mode 100644 index 0000000000..f46b88c50a --- /dev/null +++ b/integration_tests/test_import_06.py @@ -0,0 +1,8 @@ +from test_import_06_mod1 import StringIO +from test_import_06_mod2 import stringio_test + +if __name__ == '__main__': + integer_asr : str = '(Integer 4 [])' + fd : StringIO = StringIO(integer_asr) + stringio_test(fd, integer_asr) + print("Ok") diff --git a/integration_tests/test_import_06_mod1.py b/integration_tests/test_import_06_mod1.py new file mode 100644 index 0000000000..37e020cb43 --- /dev/null +++ b/integration_tests/test_import_06_mod1.py @@ -0,0 +1,5 @@ +from lpython import dataclass + +@dataclass +class StringIO: + a: str diff --git a/integration_tests/test_import_06_mod2.py b/integration_tests/test_import_06_mod2.py new file mode 100644 index 0000000000..da37cfa172 --- /dev/null +++ b/integration_tests/test_import_06_mod2.py @@ -0,0 +1,4 @@ +from test_import_06_mod1 import StringIO + +def stringio_test(fd: StringIO, integer_asr: str): + assert fd.a == integer_asr diff --git a/integration_tests/test_import_07.py b/integration_tests/test_import_07.py new file mode 100644 index 0000000000..b799410cbf --- /dev/null +++ b/integration_tests/test_import_07.py @@ -0,0 +1,8 @@ +# test issue 2153 +from test_import_07_module import f as fa + +def main0(): + assert fa(3) == 6 + assert fa(10) == 20 + +main0() diff --git a/integration_tests/test_import_07_module.py b/integration_tests/test_import_07_module.py new file mode 100644 index 0000000000..a0925aa5ae --- /dev/null +++ b/integration_tests/test_import_07_module.py @@ -0,0 +1,4 @@ +from lpython import i32 + +def f(x: i32) -> i32: + return 2 * x diff --git a/integration_tests/test_import_08.py b/integration_tests/test_import_08.py new file mode 100644 index 0000000000..80b1bffa0f --- /dev/null +++ b/integration_tests/test_import_08.py @@ -0,0 +1,3 @@ +import string + +import test_import_08_module diff --git a/integration_tests/test_import_08_module.py b/integration_tests/test_import_08_module.py new file mode 100644 index 0000000000..f92430e846 --- /dev/null +++ b/integration_tests/test_import_08_module.py @@ -0,0 +1,6 @@ +from lpython import i32 + +a: i32 = 10 +b: i32 = a + 10 + +print("Inside import") diff --git a/integration_tests/test_integer_bitnot.py b/integration_tests/test_integer_bitnot.py deleted file mode 100644 index 2c12e8ecf4..0000000000 --- a/integration_tests/test_integer_bitnot.py +++ /dev/null @@ -1,13 +0,0 @@ -from ltypes import i32 - -def f(): - i: i32 - i = 5 - res: i32 - res = ~i - assert res == -6 - - i = -235346 - assert ~i == 235345 - -f() diff --git a/integration_tests/test_intrinsic_function_mixed_print.py b/integration_tests/test_intrinsic_function_mixed_print.py new file mode 100644 index 0000000000..8c5ee2f32d --- /dev/null +++ b/integration_tests/test_intrinsic_function_mixed_print.py @@ -0,0 +1,25 @@ +from lpython import i32 + +def test_intrinsic_function_mixed_print(): + # list and list methods + my_list: list[i32] = [1, 2, 3, 4, 5] + print("Popped element:", my_list.pop()) + assert my_list == [1, 2, 3, 4] + + print("1 is located at:", my_list.index(1)) + assert my_list.index(1) == 0 + + my_list.append(2) + print("2 is present", my_list.count(2), "times") + assert my_list.count(2) == 2 + + print(my_list.pop(), my_list) + assert my_list == [1, 2, 3, 4] + + # dict and dict methods + my_dict: dict[str, i32] = {"first": 1, "second": 2, "third": 3} + print("Keys:", my_dict.keys()) + print("Value of 'third':", my_dict.pop("third")) + assert len(my_dict.keys()) == 2 + +test_intrinsic_function_mixed_print() \ No newline at end of file diff --git a/integration_tests/test_issue_518.py b/integration_tests/test_issue_518.py index cb1a4eacb9..755719a27b 100644 --- a/integration_tests/test_issue_518.py +++ b/integration_tests/test_issue_518.py @@ -1,4 +1,4 @@ -from ltypes import i64 +from lpython import i64 def fib(n: i64) -> i64: if n < i64(2): diff --git a/integration_tests/test_list_01.py b/integration_tests/test_list_01.py index a9042aa5e0..3a8789c0e1 100644 --- a/integration_tests/test_list_01.py +++ b/integration_tests/test_list_01.py @@ -1,4 +1,4 @@ -from ltypes import f64, i32 +from lpython import f64, i32 def fill_list_i32(size: i32) -> list[i32]: aarg: list[i32] = [0, 1, 2, 3, 4] @@ -63,9 +63,21 @@ def test_list_03(): for i in range(size): assert x[i] == x[((i-len(x)) + size) % size] + +def test_issue_1681(): + a: list[i32] = [2, 3, 4] + a = [1, 2, 3] + assert len(a) == 3 and a[0] == 1 and a[1] == 2 and a[2] == 3 + a = [] + assert len(a) == 0 + a = [1] + assert len(a) == 1 and a[0] == 1 + + def tests(): test_list_01() test_list_02() test_list_03() + test_issue_1681() tests() diff --git a/integration_tests/test_list_02.py b/integration_tests/test_list_02.py index 7879ffc9d0..f96d1f23d0 100644 --- a/integration_tests/test_list_02.py +++ b/integration_tests/test_list_02.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def fill_list_str(size: i32) -> list[str]: a: list[str] = ["0_str", "1_str"] diff --git a/integration_tests/test_list_03.py b/integration_tests/test_list_03.py index ee7c33b86a..1cb6953e7d 100644 --- a/integration_tests/test_list_03.py +++ b/integration_tests/test_list_03.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32, InOut def test_list_01(n: i32) -> i32: a: list[i32] = [] @@ -10,7 +10,7 @@ def test_list_01(n: i32) -> i32: sum += a[i] return sum -def test_list_insert_02(x: list[i32], n: i32) -> list[i32]: +def test_list_insert_02(x: InOut[list[i32]], n: i32) -> list[i32]: i: i32 imod: i32 for i in range(n): diff --git a/integration_tests/test_list_04.py b/integration_tests/test_list_04.py index 687745bcf1..7c09061768 100644 --- a/integration_tests/test_list_04.py +++ b/integration_tests/test_list_04.py @@ -1,5 +1,5 @@ from math import sqrt -from ltypes import i32, f64 +from lpython import i32, f64 def test_list_01(): x: list[i32] = [] diff --git a/integration_tests/test_list_05.py b/integration_tests/test_list_05.py index 088048968e..7708b95dec 100644 --- a/integration_tests/test_list_05.py +++ b/integration_tests/test_list_05.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64, InOut def check_list_of_tuples(l: list[tuple[i32, f64, str]], sign: i32): size: i32 = len(l) @@ -29,7 +29,7 @@ def fill_list_of_tuples(size: i32) -> list[tuple[i32, f64, str]]: return l1 -def insert_tuples_into_list(l: list[tuple[i32, f64, str]], size: i32) -> list[tuple[i32, f64, str]]: +def insert_tuples_into_list(l: InOut[list[tuple[i32, f64, str]]], size: i32) -> list[tuple[i32, f64, str]]: i: i32 string: str t: tuple[i32, f64, str] diff --git a/integration_tests/test_list_06.py b/integration_tests/test_list_06.py index dcede48d7e..0924b87691 100644 --- a/integration_tests/test_list_06.py +++ b/integration_tests/test_list_06.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 from copy import deepcopy def check_mat_and_vec(mat: list[list[f64]], vec: list[f64]): @@ -15,8 +15,8 @@ def check_mat_and_vec(mat: list[list[f64]], vec: list[f64]): assert vec[i] == 2.0 * float(i) def test_list_of_lists(): - tensors: list[list[list[list[f64]]]] = [] - tensor: list[list[list[f64]]] = [] + arrays: list[list[list[list[f64]]]] = [] + array: list[list[list[f64]]] = [] mat: list[list[f64]] = [] vec: list[f64] = [] rows: i32 = 10 @@ -38,7 +38,7 @@ def test_list_of_lists(): check_mat_and_vec(mat, vec) for k in range(rows): - tensor.append(deepcopy(mat)) + array.append(deepcopy(mat)) for i in range(rows): for j in range(cols): mat[i][j] += float(1) @@ -46,19 +46,19 @@ def test_list_of_lists(): for k in range(rows): for i in range(rows): for j in range(cols): - assert mat[i][j] - tensor[k][i][j] == f64(rows - k) + assert mat[i][j] - array[k][i][j] == f64(rows - k) for l in range(2 * rows): - tensors.append(deepcopy(tensor)) + arrays.append(deepcopy(array)) for i in range(rows): for j in range(rows): for k in range(cols): - tensor[i][j][k] += float(1) + array[i][j][k] += float(1) for l in range(2 * rows): for i in range(rows): for j in range(rows): for k in range(cols): - assert tensor[i][j][k] - tensors[l][i][j][k] == f64(2 * rows - l) + assert array[i][j][k] - arrays[l][i][j][k] == f64(2 * rows - l) test_list_of_lists() diff --git a/integration_tests/test_list_07.py b/integration_tests/test_list_07.py index bd33a079eb..904ee70b38 100644 --- a/integration_tests/test_list_07.py +++ b/integration_tests/test_list_07.py @@ -1,17 +1,17 @@ -from ltypes import c64, i32 +from lpython import c64, i32 from copy import deepcopy -def generate_complex_tensors(mat: list[list[c64]], vec: list[c64]) -> list[tuple[list[list[c64]], list[c64]]]: - tensor: tuple[list[list[c64]], list[c64]] - tensors: list[tuple[list[list[c64]], list[c64]]] = [] +def generate_complex_arrays(mat: list[list[c64]], vec: list[c64]) -> list[tuple[list[list[c64]], list[c64]]]: + array: tuple[list[list[c64]], list[c64]] + arrays: list[tuple[list[list[c64]], list[c64]]] = [] rows: i32 = len(mat) cols: i32 = len(vec) i: i32; j: i32; k: i32 - tensor = (deepcopy(mat), deepcopy(vec)) + array = (deepcopy(mat), deepcopy(vec)) for k in range(2 * rows): - tensors.append(deepcopy(tensor)) + arrays.append(deepcopy(array)) for i in range(rows): for j in range(cols): mat[i][j] += complex(1.0, 2.0) @@ -19,15 +19,15 @@ def generate_complex_tensors(mat: list[list[c64]], vec: list[c64]) -> list[tuple for i in range(cols): vec[i] += complex(1.0, 2.0) - tensor = (deepcopy(mat), deepcopy(vec)) + array = (deepcopy(mat), deepcopy(vec)) - return tensors + return arrays def test_tuple_with_lists(): mat: list[list[c64]] = [] vec: list[c64] = [] - tensor: tuple[list[list[c64]], list[c64]] - tensors: list[tuple[list[list[c64]], list[c64]]] = [] + array: tuple[list[list[c64]], list[c64]] + arrays: list[tuple[list[list[c64]], list[c64]]] = [] i: i32 j: i32 k: i32 @@ -48,7 +48,7 @@ def test_tuple_with_lists(): for j in range(cols): assert mat[i][j] - vec[j] == c64(i - j) - tensor = (deepcopy(mat), deepcopy(vec)) + array = (deepcopy(mat), deepcopy(vec)) for i in range(rows): for j in range(cols): @@ -59,20 +59,20 @@ def test_tuple_with_lists(): for i in range(rows): for j in range(cols): - assert tensor[0][i][j] - mat[i][j] == -complex(0, 3.0) + assert array[0][i][j] - mat[i][j] == -complex(0, 3.0) for i in range(cols): - assert tensor[1][i] - vec[i] == -complex(0, 2.0) + assert array[1][i] - vec[i] == -complex(0, 2.0) - tensors = generate_complex_tensors(mat, vec) + arrays = generate_complex_arrays(mat, vec) for k in range(2 * rows): for i in range(rows): for j in range(cols): - assert tensors[k][0][i][j] - mat[i][j] == -c64(2 * rows - k) * complex(1.0, 2.0) + assert arrays[k][0][i][j] - mat[i][j] == -c64(2 * rows - k) * complex(1.0, 2.0) for k in range(2 * rows): for i in range(cols): - assert tensors[k][1][i] - vec[i] == -c64(2 * rows - k) * complex(1.0, 2.0) + assert arrays[k][1][i] - vec[i] == -c64(2 * rows - k) * complex(1.0, 2.0) test_tuple_with_lists() diff --git a/integration_tests/test_list_08.py b/integration_tests/test_list_08.py index 21b2eb7758..f5a2cd33f3 100644 --- a/integration_tests/test_list_08.py +++ b/integration_tests/test_list_08.py @@ -1,7 +1,7 @@ -from ltypes import i32, f64 +from lpython import i32, f64, InOut from copy import deepcopy -def sort(l: list[i32]) -> list[i32]: +def sort(l: InOut[list[i32]]) -> list[i32]: i: i32; j: i32 for i in range(len(l)): diff --git a/integration_tests/test_list_09.py b/integration_tests/test_list_09.py index 2aa4a369b3..b7ca405765 100644 --- a/integration_tests/test_list_09.py +++ b/integration_tests/test_list_09.py @@ -1,4 +1,5 @@ -from ltypes import i32 +from lpython import i32 + def test_list_concat(): x: list[i32] = [] @@ -10,39 +11,41 @@ def test_list_concat(): x = [1, 2, 3] z = x + y for i in range(1, 4): - assert z[i-1] == i + assert z[i - 1] == i x.clear() y = [6, 7, 8] z = x + y for i in range(1, 4): - assert z[i-1] == i + 5 + assert z[i - 1] == i + 5 x = [1, 2, 3, 4, 5] z = x + y for i in range(1, 9): - assert z[i-1] == i + assert z[i - 1] == i - x.clear(); y.clear() + x.clear() + y.clear() for i in range(9, 51): x.append(i) for i in range(51, 101): y.append(i) z = z + x + y - x[0] = 0; x[1] = 0 + x[0] = 0 + x[1] = 0 y.clear() for i in range(1, 100): - assert z[i-1] == i - + assert z[i - 1] == i + c: list[str] d: list[str] - c = ['a', 'b'] - d = ['c', 'd', 'e'] + c = ["a", "b"] + d = ["c", "d", "e"] c += d assert len(c) == 5 for i in range(5): - assert ord(c[i]) - ord('a') == i + assert ord(c[i]) - ord("a") == i test_list_concat() diff --git a/integration_tests/test_list_10.py b/integration_tests/test_list_10.py index c938e56cbb..5216054ddf 100644 --- a/integration_tests/test_list_10.py +++ b/integration_tests/test_list_10.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_list_section(): x: list[i32] = [] diff --git a/integration_tests/test_list_11.py b/integration_tests/test_list_11.py new file mode 100644 index 0000000000..2cb899ebf2 --- /dev/null +++ b/integration_tests/test_list_11.py @@ -0,0 +1,46 @@ +from lpython import i32 + +l: list[i32] = [1, 2] + +def add_item(i: i32) -> list[i32]: + l.append(i) + return l + + +def return_empty_list_of_tuples() -> list[i32]: + return [] + + +def test_issue_1882(): + i: i32 + x: list[i32] + x = [2, 3, 4] + for i in [1, 2, 3]: + assert i + 1 == x[i - 1] + +def test_iterate_over_string(): + s: str + i: i32 = 0 + temp: str = "abcd" + for s in "abcd": + assert s == temp[i] + i+=1 + +def test_issue_2639(): + print(add_item(3)) + + assert len(l) == 3 + assert l[0] == 1 + assert l[1] == 2 + assert l[2] == 3 + +def main0(): + x: list[i32] = return_empty_list_of_tuples() + print(len(x)) + + assert len(x) == 0 + test_issue_1882() + test_iterate_over_string() + test_issue_2639() + +main0() diff --git a/integration_tests/test_list_compare.py b/integration_tests/test_list_compare.py new file mode 100644 index 0000000000..24fcc485d5 --- /dev/null +++ b/integration_tests/test_list_compare.py @@ -0,0 +1,53 @@ +from lpython import i32, f64 + +def test_list_compare(): + l1: list[i32] = [1, 2, 3] + l2: list[i32] = [1, 2, 3, 4] + l3: list[tuple[i32, f64, str]] = [(1, 2.0, 'a'), (3, 4.0, 'b')] + l4: list[tuple[i32, f64, str]] = [(1, 3.0, 'a')] + l5: list[list[str]] = [[''], ['']] + l6: list[str] = [] + l7: list[str] = [] + t1: tuple[i32, i32] + t2: tuple[i32, i32] + i: i32 + + assert l1 < l2 and l1 <= l2 + assert not l1 > l2 and not l1 >= l2 + i = l2.pop() + i = l2.pop() + assert l2 < l1 and l1 > l2 and l1 >= l2 + assert not (l1 < l2) + + l1 = [3, 4, 5] + l2 = [1, 6, 7] + assert l1 > l2 and l1 >= l2 + assert not l1 < l2 and not l1 <= l2 + + l1 = l2 + assert l1 == l2 and l1 <= l2 and l1 >= l2 + assert not l1 < l2 and not l1 > l2 + + assert l4 > l3 and l4 >= l3 + l4[0] = l3[0] + assert l4 < l3 + + for i in range(0, 10): + if i % 2 == 0: + l6.append('a') + else: + l7.append('a') + l5[0] = l6 + l5[1] = l7 + if i % 2 == 0: + assert l5[1 - i % 2] < l5[i % 2] + assert l5[1 - i % 2] <= l5[i % 2] + assert not l5[1 - i % 2] > l5[i % 2] + assert not l5[1 - i % 2] >= l5[i % 2] + + t1 = (1, 2) + t2 = (2, 3) + assert t1 < t2 and t1 <= t2 + assert not t1 > t2 and not t1 >= t2 + +test_list_compare() \ No newline at end of file diff --git a/integration_tests/test_list_compare2.py b/integration_tests/test_list_compare2.py new file mode 100644 index 0000000000..9778c9a2a7 --- /dev/null +++ b/integration_tests/test_list_compare2.py @@ -0,0 +1,8 @@ +from lpython import i32 + +x: list[i32] = [1, 2, 3, 4] +y: list[i32] = [5, 6, 7, 8] +z: list[i32] = [1, 2, 3, 4] + +assert(x != y) +assert(x == z) \ No newline at end of file diff --git a/integration_tests/test_list_concat.py b/integration_tests/test_list_concat.py new file mode 100644 index 0000000000..2cf2b583a2 --- /dev/null +++ b/integration_tests/test_list_concat.py @@ -0,0 +1,18 @@ +from lpython import i32, f64 + +def test_list_concat(): + t1: list[i32] + t1 = [2] + [3] + print(t1) + assert len(t1) == 2 + assert t1[0] == 2 + assert t1[1] == 3 + + t2: list[f64] + t2 = [3.14, -4.5] + [1.233, -0.012, 5555.50] + print(t2) + assert len(t2) == 5 + assert abs(t2[0] - 3.14) <= 1e-5 + assert abs(t2[-1] - 5555.50) <= 1e-5 + +test_list_concat() diff --git a/integration_tests/test_list_count.py b/integration_tests/test_list_count.py new file mode 100644 index 0000000000..98c64fd6cb --- /dev/null +++ b/integration_tests/test_list_count.py @@ -0,0 +1,55 @@ +from lpython import i32, f64 + +def test_list_count(): + i: i32 + x: list[i32] = [] + y: list[str] = [] + z: list[tuple[i32, str, f64]] = [] + + for i in range(-5, 0): + assert x.count(i) == 0 + x.append(i) + assert x.count(i) == 1 + x.append(i) + assert x.count(i) == 2 + x.remove(i) + assert x.count(i) == 1 + + assert x == [-5, -4, -3, -2, -1] + + for i in range(0, 5): + assert x.count(i) == 0 + x.append(i) + assert x.count(i) == 1 + + assert x == [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] + + while len(x) > 0: + i = x[-1] + x.remove(i) + assert x.count(i) == 0 + + assert len(x) == 0 + assert x.count(0) == 0 + + # str + assert y.count('a') == 0 + y = ['a', 'abc', 'a', 'b'] + assert y.count('a') == 2 + y.append('a') + assert y.count('a') == 3 + y.remove('a') + assert y.count('a') == 2 + + # tuple, float + assert z.count((i32(-1), 'b', f64(2))) == 0 + z = [(i32(1), 'a', f64(2.01)), (i32(-1), 'b', f64(2)), (i32(1), 'a', f64(2.02))] + assert z.count((i32(1), 'a', f64(2.00))) == 0 + assert z.count((i32(1), 'a', f64(2.01))) == 1 + z.append((i32(1), 'a', f64(2))) + z.append((i32(1), 'a', f64(2.00))) + assert z.count((i32(1), 'a', f64(2))) == 2 + z.remove((i32(1), 'a', f64(2))) + assert z.count((i32(1), 'a', f64(2.00))) == 1 + +test_list_count() diff --git a/integration_tests/test_list_index.py b/integration_tests/test_list_index.py new file mode 100644 index 0000000000..b74410bf1f --- /dev/null +++ b/integration_tests/test_list_index.py @@ -0,0 +1,40 @@ +from lpython import i32, f64 + +def test_list_index(): + i: i32 + x: list[i32] = [] + y: list[str] = [] + z: list[tuple[i32, str, f64]] = [] + + for i in range(-5, 0): + x.append(i) + assert x.index(i) == len(x)-1 + x.append(i) + assert x.index(i) == len(x)-2 + x.remove(i) + assert x.index(i) == len(x)-1 + + assert x == [-5, -4, -3, -2, -1] + + for i in range(-5, 0): + x.append(i) + assert x.index(i) == 0 + x.remove(i) + assert x.index(i) == len(x)-1 + + # str + y = ['a', 'abc', 'a', 'b', 'abc'] + assert y.index('a') == 0 + assert y.index('abc') == 1 + + # tuple, float + z = [(i32(1), 'a', f64(2.01)), (i32(-1), 'b', f64(2)), (i32(1), 'a', f64(2.02))] + assert z.index((i32(1), 'a', f64(2.01))) == 0 + z.insert(0, (i32(1), 'a', f64(2))) + assert z.index((i32(1), 'a', f64(2.00))) == 0 + z.append((i32(1), 'a', f64(2.00))) + assert z.index((i32(1), 'a', f64(2))) == 0 + z.remove((i32(1), 'a', f64(2))) + assert z.index((i32(1), 'a', f64(2.00))) == 3 + +test_list_index() \ No newline at end of file diff --git a/integration_tests/test_list_index2.py b/integration_tests/test_list_index2.py new file mode 100644 index 0000000000..9e74e929b4 --- /dev/null +++ b/integration_tests/test_list_index2.py @@ -0,0 +1,55 @@ +from lpython import i32, f64 + +def test_list_index2(): + # test optional start and end parameters + i: i32 + x: list[i32] = [] + y: list[str] = [] + z: list[tuple[i32, str, f64]] = [] + + x = [1, 2, 3, 2] + assert x.index(2, 0) == 1 + assert x.index(2, 1) == 1 + assert x.index(2, 2) == 3 + assert x.index(2, 1, 4) == 1 + assert x.index(2, 2, 4) == 3 + + x = [] + for i in range(-5, 0): + x.append(i) + assert x.index(i, 0) == len(x) - 1 + assert x.index(i, 0, len(x)) == len(x) - 1 + x.append(i) + assert x.index(i, 0) == len(x) - 2 + assert x.index(i, 0, len(x)) == len(x) - 2 + assert x.index(i, len(x) - 1) == len(x) - 1 + assert x.index(i, len(x) - 1, len(x)) == len(x) - 1 + x.remove(i) + assert x.index(i, 0) == len(x) - 1 + assert x.index(i, 0, len(x)) == len(x) - 1 + + assert x == [-5, -4, -3, -2, -1] + + # str + y = ['a', 'abc', 'a', 'b', 'abc'] + assert y.index('a', 0) == 0 + assert y.index('a', 0, 1) == 0 + assert y.index('a', 1) == 2 + assert y.index('a', 1, 3) == 2 + assert y.index('abc', 0) == 1 + assert y.index('abc', 1) == 1 + assert y.index('abc', 2) == 4 + + # tuple, float + z = [(1, 'a', 2.01), (-1, 'b', 2.0), (1, 'a', 2.02)] + assert z.index((1, 'a', 2.01), 0) == 0 + assert z.index((1, 'a', 2.01), 0, 1) == 0 + z.insert(0, (1, 'a', 2.0)) + assert z.index((1, 'a', 2.0), 0) == 0 + assert z.index((-1, 'b', 2.0), 1) == 2 + z.insert(0, (1, 'a', 2.0)) + assert z.index((-1, 'b', 2.0), 1) == 3 + assert z.index((-1, 'b', 2.0), 1, 4) == 3 + assert z.index((-1, 'b', 2.0), 1, 5) == 3 + +test_list_index2() \ No newline at end of file diff --git a/integration_tests/test_list_item_mixed_print.py b/integration_tests/test_list_item_mixed_print.py new file mode 100644 index 0000000000..10fdc32b75 --- /dev/null +++ b/integration_tests/test_list_item_mixed_print.py @@ -0,0 +1,44 @@ +from lpython import i32, f64 + +# Test for verifying printing items of different types with a list: +# 1. string and list item +# 2. integer and list item +# 3. float and list item +# 4. tuple and list item +# +# Also test with a list item which is a nested list. +def test_list_item_mixed_print(): + s_list: list[str] = ["Hello", "LPython"] + + print("", s_list[0]) + print("This is", s_list[1]) + + i_list: list[i32] = [1, 2, 3, 4, 5] + + print(i_list[0], i_list[1], i_list[2], "...", i_list[-3], i_list[-2], i_list[-1]) + print("The first element is:", i_list[0]) + + m: i32 = len(i_list) // 2 + print("The middle element is:", i_list[m]) + + f_list: list[f64] = [3.14, 6.28] + + print(f_list[0], "* 2 =", f_list[1]) + print("Total:", f_list[0] + f_list[1]) + + t: tuple[i32, i32, i32] = (1, 2, 3) + print(t, "is a tuple, but", i_list[0], "is a number.") + + i_list2: list[i32] = [1, 2, 3] + print(i_list2[0], i_list2[1], i_list2[2], sep=" is smaller than ") + + i: i32 + for i in range(len(i_list)): + print(i_list[i], end=" # ") + print("\n") + + n_list: list[list[i32]] = [[1, 2], [3, 4], [5, 6]] + for i in range(len(n_list)): + print("List ", i, ":", n_list[i]) + +test_list_item_mixed_print() \ No newline at end of file diff --git a/integration_tests/test_list_pop.py b/integration_tests/test_list_pop.py new file mode 100644 index 0000000000..da2db3e5fd --- /dev/null +++ b/integration_tests/test_list_pop.py @@ -0,0 +1,96 @@ +from lpython import i32, f64 + +def test_list_pop(): + l1: list[i32] + l2: list[tuple[i32, f64]] + l3: list[list[str]] + i: i32 + j: i32 + total: i32 + x: tuple[i32, f64] + + l1 = [1, 2, 3] + assert l1.pop() == 3 + assert l1 == [1, 2] + + l1 = [] + total = 10 + for i in range(total): + l1.append(i) + if i % 2 == 1: + assert l1.pop() == i + for i in range(total // 2): + assert l1[i] == 2 * i + + l2 = [(1, 2.0)] + x = l2.pop() + assert x == (1, 2.0) + assert len(l2) == 0 + l2.append((2, 3.0)) + assert x == (1, 2.0) + + l3 = [] + for i in range(total): + l3.insert(0, ["a"]) + for j in range(len(l3)): + l3[j] += ["a"] + while len(l3) > 0: + total = len(l3) + assert len(l3.pop()) == total + 1 + assert len(l3) == 0 + + l1 = [0, 1, 2, 3, 4] + assert l1.pop(3) == 3 + assert l1.pop(0) == 0 + assert l1.pop(len(l1) - 1) == 4 + assert l1 == [1, 2] + + total = 10 + l1 = [] + for i in range(total): + l1.append(i) + j = 0 + for i in range(total): + assert l1.pop(j - i) == i + j += 1 + assert len(l1) == 0 + + total = 10 + l2 = [] + for i in range(total): + l2.append((i, f64(i * i))) + j = 0 + for i in range(total): + assert l2.pop(j - i) == (i, f64(i * i)) + j += 1 + assert len(l2) == 0 + + # list.pop on list constant + print([1, 2, 3, 4, 5].pop()) + assert [1, 2, 3, 4, 5].pop() == 5 + + print([1, 2, 3, 4, 5].pop(3)) + assert [1, 2, 3, 4, 5].pop(3) == 4 + + index: i32 = 1 + print([1, 2, 3, 4, 5].pop(index)) + assert [1, 2, 3, 4, 5].pop(index) == 2 + + element_1: i32 = [1, 2, 3, 4, 5].pop() + print(element_1) + assert element_1 == 5 + + element_2: i32 = [1, 2, 3, 4, 5].pop(2) + print(element_2) + assert element_2 == 3 + + a: i32 = 5 + b: i32 = 3 + + print([(1, 2), (3, 4), (5, 6)].pop(a//b)) + assert [(1, 2), (3, 4), (5, 6)].pop(a//b) == (3, 4) + + print([["a", "b"], ["c", "d"], ["e", "f"]].pop()) + assert [["a", "b"], ["c", "d"], ["e", "f"]].pop() == ["e", "f"] + +test_list_pop() \ No newline at end of file diff --git a/integration_tests/test_list_pop2.py b/integration_tests/test_list_pop2.py new file mode 100644 index 0000000000..cee56b3684 --- /dev/null +++ b/integration_tests/test_list_pop2.py @@ -0,0 +1,22 @@ +from lpython import i32, f64, InOut + +def pop_wrapper(l: InOut[list[tuple[i32, f64]]], idx: i32) -> tuple[i32, f64]: + return l.pop(idx) + +def test_list_pop(): + l1: list[tuple[i32, f64]] + x: tuple[i32, f64] + i: i32 + + l1 = [(1, 1.0), (2, 4.0), (3, 6.0)] + + x = pop_wrapper(l1, 0) + assert x == (1, 1.0) + + l1.append((4, 8.0)) + assert x == (1, 1.0) + + for i in range(len(l1)): + assert l1[i] == (i + 2, 2.0 * f64(i + 2)) + +test_list_pop() \ No newline at end of file diff --git a/integration_tests/test_list_pop3.py b/integration_tests/test_list_pop3.py new file mode 100644 index 0000000000..13f0740a67 --- /dev/null +++ b/integration_tests/test_list_pop3.py @@ -0,0 +1,14 @@ +from lpython import i32 + +def main0(): + a: list[i32] = [3, 4, 5] + i: i32 + for i in range(10): + a.append(1) + a.pop() + + print(a) + assert a[-1] == 5 + assert len(a) == 3 + +main0() diff --git a/integration_tests/test_list_repeat.py b/integration_tests/test_list_repeat.py new file mode 100644 index 0000000000..1c9b1bbc81 --- /dev/null +++ b/integration_tests/test_list_repeat.py @@ -0,0 +1,41 @@ +from lpython import i32, f64 + +def test_list_repeat(): + l_int_1: list[i32] = [1, 2] + l_int_2: list[i32] = [] + l_int_3: list[i32] + l_tuple_1: list[tuple[f64, i32]] = [(1.0, 2), (2.0, 4), (3.0, 6)] + l_tuple_2: list[tuple[f64, i32]] = [] + l_tuple_3: list[tuple[f64, i32]] + l_str_1: list[str] = ['ab', 'cd'] + l_str_2: list[str] = [] + l_str_3: list[str] + i: i32 + + assert len(l_int_1 * 0) == 0 + assert l_int_1 * 1 == [1, 2] + assert l_int_1 * 2 == [1, 2, 1, 2] + + for i in range(10): + l_int_3 = l_int_1 * i + assert l_int_3 == l_int_2 + l_int_2 += l_int_1 + + l_tuple_3 = l_tuple_1 * i + assert l_tuple_3 == l_tuple_2 + l_tuple_2 += l_tuple_1 + + l_str_3 = l_str_1 * i + assert l_str_3 == l_str_2 + l_str_2 += l_str_1 + + for i in range(5): + assert l_int_1 * i + l_int_1 * (i + 1) == l_int_1 * (2 * i + 1) + assert l_tuple_1 * i + l_tuple_1 * (i + 1) == l_tuple_1 * (2 * i + 1) + assert l_str_1 * i + l_str_1 * (i + 1) == l_str_1 * (2 * i + 1) + + print(l_int_1) + print(l_tuple_1) + print(l_tuple_1) + +test_list_repeat() diff --git a/integration_tests/test_list_repeat2.py b/integration_tests/test_list_repeat2.py new file mode 100644 index 0000000000..f152e691ca --- /dev/null +++ b/integration_tests/test_list_repeat2.py @@ -0,0 +1,24 @@ +from lpython import i32, f32 + +def add_list(x: list[f32]) -> f32: + sum: f32 = f32(0.0) + i: i32 + + for i in range(len(x)): + sum = sum + f32(x[i]) + return sum + +def create_list(n: i32) -> list[f32]: + x: list[f32] + i: i32 + + x = [f32(0.0)] * n + for i in range(n): + x[i] = f32(i) + return x + +def main0(): + x: list[f32] = create_list(i32(10)) + print(add_list(x)) + +main0() diff --git a/integration_tests/test_list_reserve.py b/integration_tests/test_list_reserve.py new file mode 100644 index 0000000000..f359d7547d --- /dev/null +++ b/integration_tests/test_list_reserve.py @@ -0,0 +1,30 @@ +from lpython import i32, f64, reserve + +def test_list_reserve(): + l1: list[i32] = [] + l2: list[list[tuple[f64, str, tuple[i32, f64]]]] = [] + i: i32 + + reserve(l1, 100) + # for i in range(50): + # l1.append(i) + # assert len(l1) == i + 1 + + # reserve(l1, 150) + + # for i in range(50): + # l1.pop(0) + # assert len(l1) == 49 - i + + # reserve(l2, 100) + # for i in range(50): + # l2.append([(f64(i * i), str(i), (i, f64(i + 1))), (f64(i), str(i), (i, f64(i)))]) + # assert len(l2) == i + 1 + + # reserve(l2, 150) + + # for i in range(50): + # l2.pop(0) + # assert len(l2) == 49 - i + +test_list_reserve() diff --git a/integration_tests/test_list_reverse.py b/integration_tests/test_list_reverse.py new file mode 100644 index 0000000000..ca8595756c --- /dev/null +++ b/integration_tests/test_list_reverse.py @@ -0,0 +1,57 @@ +from lpython import i32, f64 + +def test_list_reverse(): + l1: list[i32] = [] + l2: list[i32] = [] + l3: list[f64] = [] + l4: list[f64] = [] + l5: list[str] = [] + l6: list[str] = [] + l7: list[str] = [] + l8: list[list[i32]] = [] + l9: list[tuple[i32, f64, str]] = [] + i: i32 + j: f64 + s: str + + l1 = [1, 2, 3] + l1.reverse() + assert l1 == [3, 2, 1] + + l1 = [] + for i in range(10): + l1.reverse() + l1.append(i) + l2.insert(0, i) + l1.reverse() + assert l1 == l2 + + j = 0.0 + while j < 2.1: + l3.reverse() + l3.append(j) + l4.insert(0, j) + l3.insert(0, j + 1.0) + l4.append(j + 1.0) + l3.reverse() + assert l3 == l4 + j += 0.1 + + l5 = ["abcd", "efgh", "ijkl"] + for s in l5: + l6.reverse() + l6.insert(0, s) + l7.append(s) + l6.reverse() + assert l6 == l7 + + l8 = [[1, 2], [3, 4, 5], [6, 7, 8, 9], [10]] + l8.reverse() + assert l8 == [[10], [6, 7, 8, 9], [3, 4, 5], [1, 2]] + + l9 = [(1, 2.0, "abc"), (3, 4.0, "def"), (5, 6.0, "ghi")] + l9.reverse() + assert l9 == [(5, 6.0, "ghi"), (3, 4.0, "def"), (1, 2.0, "abc")] + + +test_list_reverse() diff --git a/integration_tests/test_list_section.py b/integration_tests/test_list_section.py index 3c59383d79..639e639a55 100644 --- a/integration_tests/test_list_section.py +++ b/integration_tests/test_list_section.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def test_issue_1369(): diff --git a/integration_tests/test_list_section2.py b/integration_tests/test_list_section2.py new file mode 100644 index 0000000000..493a6c407c --- /dev/null +++ b/integration_tests/test_list_section2.py @@ -0,0 +1,12 @@ +from lpython import i32 + + +def test_list_section(): + x: list[i32] + x = [5, -6, 7, -1, 2, 10, -8, 15] + + n: i32 = len(x[1:4]) + print(n) + assert n == 3 + +test_list_section() diff --git a/integration_tests/test_logical_assignment.py b/integration_tests/test_logical_assignment.py new file mode 100644 index 0000000000..86c03a8d2b --- /dev/null +++ b/integration_tests/test_logical_assignment.py @@ -0,0 +1,21 @@ +from lpython import i32, f64 + + +def test_logical_assignment(): + _LPYTHON: str = "LPython" + s_var: str = "" or _LPYTHON + assert s_var == "LPython" + print(s_var) + + _MAX_VAL: i32 = 100 + i_var: i32 = 0 and 100 + assert i_var == 0 + print(i_var) + + _PI: f64 = 3.14 + f_var: f64 = 2.0 * _PI or _PI**2.0 + assert f_var == 6.28 + print(f_var) + + +test_logical_assignment() diff --git a/integration_tests/test_logical_compare.py b/integration_tests/test_logical_compare.py new file mode 100644 index 0000000000..538598c29a --- /dev/null +++ b/integration_tests/test_logical_compare.py @@ -0,0 +1,129 @@ +from lpython import i32, f64 + + +def test_logical_compare_literal(): + # Integers + print(1 or 3) + assert (1 or 3) == 1 + + print(1 and 3) + assert (1 and 3) == 3 + + print(2 or 3 or 5 or 6) + assert (2 or 3 or 5 or 6) == 2 + + print(1 and 3 or 2 and 4) + assert (1 and 3 or 2 and 4) == 3 + + print(1 or 3 and 0 or 4) + assert (1 or 3 and 0 or 4) == 1 + + print(1 and 3 or 2 and 0) + assert (1 and 3 or 2 and 0) == 3 + + print(1 and 0 or 3 and 4) + assert (1 and 0 or 3 and 4) == 4 + + # Floating-point numbers + print(1.33 or 6.67) + assert (1.33 or 6.67) == 1.33 + + print(1.33 and 6.67) + assert (1.33 and 6.67) == 6.67 + + print(1.33 or 6.67 and 3.33 or 0.0) + assert (1.33 or 6.67 and 3.33 or 0.0) == 1.33 + + print(1.33 and 6.67 or 3.33 and 0.0) + assert (1.33 and 6.67 or 3.33 and 0.0) == 6.67 + + print(1.33 and 0.0 and 3.33 and 6.67) + assert (1.33 and 0.0 and 3.33 and 6.67) == 0.0 + + # Strings + print("a" or "b") + assert ("a" or "b") == "a" + + print("abc" or "b") + assert ("abc" or "b") == "abc" + + print("a" and "b") + assert ("a" and "b") == "b" + + print("a" or "b" and "c" or "d") + assert ("a" or "b" and "c" or "d") == "a" + + print("" or " ") + assert ("" or " ") == " " + + print("" and " " or "a" and "b" and "c") + assert ("" and " " or "a" and "b" and "c") == "c" + + print("" and " " and "a" and "b" and "c") + assert ("" and " " and "a" and "b" and "c") == "" + + +def test_logical_compare_variable(): + # Integers + i_a: i32 = 1 + i_b: i32 = 3 + + print(i_a and i_b) + assert (i_a and i_b) == 3 + + print(i_a or i_b or 2 or 4) + assert (i_a or i_b or 2 or 4) == 1 + + print(i_a and i_b or 2 and 4) + assert (i_a and i_b or 2 and 4) == 3 + + print(i_a or i_b and 0 or 4) + assert (i_a or i_b and 0 or 4) == i_a + + print(i_a and i_b or 2 and 0) + assert (i_a and i_b or 2 and 0) == i_b + + print(i_a and 0 or i_b and 4) + assert (i_a and 0 or i_b and 4) == 4 + + print(i_a + i_b or 0 - 4) + assert (i_a + i_b or 0 - 4) == 4 + + # Floating-point numbers + f_a: f64 = 1.67 + f_b: f64 = 3.33 + + print(f_a // f_b and f_a - f_b) + assert (f_a // f_b and f_a - f_b) == 0.0 + + print(f_a**3.0 or 3.0**f_a) + assert (f_a**3.0 or 3.0**f_a) == 4.657462999999999 + + print(f_a - 3.0 and f_a + 3.0 or f_b - 3.0 and f_b + 3.0) + assert (f_a - 3.0 and f_a + 3.0 or f_b - 3.0 and f_b + 3.0) == 4.67 + + # Strings + s_a: str = "a" + s_b: str = "b" + + print(s_a or s_b) + assert (s_a or s_b) == s_a + + print(s_a and s_b) + assert (s_a and s_b) == s_b + + print(s_a + s_b or s_b + s_a) + assert (s_a + s_b or s_b + s_a) == "ab" + + print(s_a[0] or s_b[-1]) + assert (s_a[0] or s_b[-1]) == "a" + + print(s_a[0] and s_b[-1]) + assert (s_a[0] and s_b[-1]) == "b" + + print(s_a + s_b or s_b + s_a + s_a[0] and s_b[-1]) + assert (s_a + s_b or s_b + s_a + s_a[0] and s_b[-1]) == "ab" + + +test_logical_compare_literal() +test_logical_compare_variable() diff --git a/integration_tests/test_math.py b/integration_tests/test_math.py index 315b4efb8e..b79d82f161 100644 --- a/integration_tests/test_math.py +++ b/integration_tests/test_math.py @@ -1,8 +1,8 @@ from math import (factorial, isqrt, perm, comb, degrees, radians, exp, pow, ldexp, fabs, gcd, lcm, floor, ceil, remainder, expm1, fmod, log1p, trunc, - modf, fsum, prod, dist) + modf, fsum, prod, dist, frexp, isclose) import math -from ltypes import i32, i64, f32, f64 +from lpython import i8, i16, i32, i64, f32, f64 eps: f64 eps = 1e-12 @@ -60,7 +60,6 @@ def test_exp(): i = exp(2.34) assert abs(i - 10.381236562731843) < eps - def test_pow(): eps: f64 eps = 1e-12 @@ -254,6 +253,58 @@ def test_issue_1242(): assert abs(math.pi - 3.14159265358979323846) < 1e-10 +def test_frexp(): + x:f64 = 6.23 + mantissa:f64 + exponent:i16 + mantissa, exponent = frexp(x) + assert abs(mantissa - 0.77875) < eps and exponent == i16(3) + + x = 0.8 + mantissa, exponent = frexp(x) + assert abs(mantissa - 0.8) < eps and exponent == i16(0) + + x = 19.74 + mantissa, exponent = frexp(x) + assert abs(mantissa - 0.616875) < eps and exponent == i16(5) + + x = -23.6 + mantissa, exponent = frexp(x) + assert abs(mantissa + 0.7375) < eps and exponent == i16(5) + + y:f32 = f32(1.23) + mantissa2:f32 + exponent2:i8 + mantissa2, exponent2 = frexp(y) + assert abs(mantissa2 - f32(0.615)) < f32(eps) and exponent2 == i8(1) + + y = f32(-1.23) + mantissa2, exponent2 = frexp(y) + assert abs(mantissa2 - f32(-0.615)) < f32(eps) and exponent2 == i8(1) + + +def test_isclose(): + x:f64 = 2.2130 + y:f64 = 2.2129 + assert isclose(x, y, rel_tol=0.01, abs_tol=0.001) + assert isclose(x,y,rel_tol=0.0000001,abs_tol=0.01) + assert isclose(x,y,rel_tol=0.1,abs_tol=0.000001) + assert not isclose(x,y,rel_tol=0.0000001,abs_tol=0.00001) + + x = -1.265 + y = 1.265 + assert not isclose(x,y,rel_tol=0.001,abs_tol=0.0001) + assert not isclose(y,x,rel_tol=0.01,abs_tol=0.1) + assert not isclose(x,y,rel_tol=0.01,abs_tol=0.1) + + x = -1.2650 + y = -1.2651 + assert isclose(x, y, rel_tol=0.01, abs_tol=0.001) + assert isclose(x,y,rel_tol=0.0000001,abs_tol=0.01) + assert isclose(x,y,rel_tol=0.1,abs_tol=0.000001) + assert not isclose(x,y,rel_tol=0.0000001,abs_tol=0.00001) + + def check(): test_factorial_1() test_comb() @@ -279,6 +330,8 @@ def check(): test_dist() test_modf() test_issue_1242() + test_frexp() + test_isclose() check() diff --git a/integration_tests/test_math1.py b/integration_tests/test_math1.py index b9e4bda987..41c4441660 100644 --- a/integration_tests/test_math1.py +++ b/integration_tests/test_math1.py @@ -1,6 +1,6 @@ import math from math import pi, e -from ltypes import i32 +from lpython import i32 def f(): diff --git a/integration_tests/test_math_02.py b/integration_tests/test_math_02.py index b154fcb152..a15b604326 100644 --- a/integration_tests/test_math_02.py +++ b/integration_tests/test_math_02.py @@ -1,20 +1,20 @@ from math import (sin, cos, tan, pi, sqrt, log, log10, log2, erf, erfc, gamma, lgamma, asin, acos, atan, atan2, asinh, acosh, atanh, tanh, sinh, cosh, hypot, copysign) -from ltypes import f64 +from lpython import f64 def test_trig(): eps: f64 = 1e-12 assert abs(sin(0.0) - 0.0) < eps - assert abs(sin(pi/2) - 1.0) < eps + assert abs(sin(pi/2.0) - 1.0) < eps assert abs(cos(0.0) - 1.0) < eps - assert abs(cos(pi/2) - 0.0) < eps + assert abs(cos(pi/2.0) - 0.0) < eps assert abs(tan(0.0) - 0.0) < eps - assert abs(tan(pi/4) - 1.0) < eps - assert abs(asin(1.0) - pi/2) < eps + assert abs(tan(pi/4.0) - 1.0) < eps + assert abs(asin(1.0) - pi/2.0) < eps assert abs(acos(1.0) - 0.0) < eps - assert abs(atan(1.0) - pi/4) < eps - assert abs(atan2(1.0, 1.0) - pi/4) < eps + assert abs(atan(1.0) - pi/4.0) < eps + assert abs(atan2(1.0, 1.0) - pi/4.0) < eps def test_sqrt(): eps: f64 = 1e-12 diff --git a/integration_tests/test_math_03.py b/integration_tests/test_math_03.py new file mode 100644 index 0000000000..8047ce2c24 --- /dev/null +++ b/integration_tests/test_math_03.py @@ -0,0 +1,21 @@ +from math import (cbrt, exp2) +from lpython import f64 + +eps: f64 +eps = 1e-12 + +def test_exp2(): + i: f64 + i = exp2(4.3) + assert abs(i - 19.698310613518657) < eps + +def test_cbrt(): + eps: f64 = 1e-12 + assert abs(cbrt(124.0) - 4.986630952238646) < eps + assert abs(cbrt(39.0) - 3.3912114430141664) < eps + +def check(): + test_cbrt() + test_exp2() + +check() \ No newline at end of file diff --git a/integration_tests/test_max_min.py b/integration_tests/test_max_min.py index 80eb924a10..79462ec2f4 100644 --- a/integration_tests/test_max_min.py +++ b/integration_tests/test_max_min.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def test_max_int(): a: i32 = 1 diff --git a/integration_tests/test_membership_01.py b/integration_tests/test_membership_01.py new file mode 100644 index 0000000000..10cb4f682e --- /dev/null +++ b/integration_tests/test_membership_01.py @@ -0,0 +1,48 @@ +def test_int_dict(): + a: dict[i32, i32] = {1:2, 2:3, 3:4, 4:5} + i: i32 + assert (1 in a) + assert (6 not in a) + i = 4 + assert (i in a) + + a = {} + assert (1 not in a) + +def test_str_dict(): + a: dict[str, str] = {'a':'1', 'b':'2', 'c':'3'} + i: str + assert ('a' in a) + assert ('d' not in a) + i = 'c' + assert (i in a) + + a = {} + assert ('a' not in a) + +def test_int_set(): + a: set[i32] = {1, 2, 3, 4} + i: i32 + assert (1 in a) + assert (6 not in a) + i = 4 + assert (i in a) + + a = set() + assert (1 not in a) + +def test_str_set(): + a: set[str] = {'a', 'b', 'c', 'e', 'f'} + i: str + assert ('a' in a) + assert ('d' not in a) + i = 'c' + assert (i in a) + + a = set() + assert ('a' not in a) + +test_int_dict() +test_str_dict() +test_int_set() +test_str_set() diff --git a/test_modules/__init__.py b/integration_tests/test_modules/__init__.py similarity index 100% rename from test_modules/__init__.py rename to integration_tests/test_modules/__init__.py diff --git a/test_modules/mathfn/__init__.py b/integration_tests/test_modules/mathfn/__init__.py similarity index 100% rename from test_modules/mathfn/__init__.py rename to integration_tests/test_modules/mathfn/__init__.py diff --git a/test_modules/mathfn/sin.py b/integration_tests/test_modules/mathfn/sin.py similarity index 78% rename from test_modules/mathfn/sin.py rename to integration_tests/test_modules/mathfn/sin.py index d7724ea4f1..4d26103b13 100644 --- a/test_modules/mathfn/sin.py +++ b/integration_tests/test_modules/mathfn/sin.py @@ -1,4 +1,4 @@ -from ltypes import f64 +from lpython import f64 def sinx(x: f64) -> f64: return x + 1.0 diff --git a/integration_tests/test_numpy_01.py b/integration_tests/test_numpy_01.py index 6b4119b972..85685d01df 100644 --- a/integration_tests/test_numpy_01.py +++ b/integration_tests/test_numpy_01.py @@ -1,11 +1,11 @@ # This test handles various aspects of local arrays using the `numpy.empty()` # function -from ltypes import f64, i32 -from numpy import empty +from lpython import f64, i32 +from numpy import empty, float64 def test_local_arrays(): a: f64[16] - a = empty(16) + a = empty(16, dtype=float64) i: i32 for i in range(16): a[i] = f64(i) + 0.5 @@ -18,7 +18,7 @@ def test_local_arrays(): def f() -> f64[4]: a: f64[4] - a = empty(4) + a = empty(4, dtype=float64) i: i32 for i in range(4): a[i] = 1.0 * f64(i) diff --git a/integration_tests/test_numpy_02.py b/integration_tests/test_numpy_02.py index 7b23ac2a4b..920b102dbf 100644 --- a/integration_tests/test_numpy_02.py +++ b/integration_tests/test_numpy_02.py @@ -1,7 +1,7 @@ # This test handles actual LPython implementations of functions from the numpy # module. -from ltypes import i32, i64, f32, f64, c32, c64, TypeVar, overload -from numpy import empty, int64 +from lpython import i32, i64, f32, f64, c32, c64, TypeVar, overload +from numpy import empty, int64, float64 e: f64 = 2.718281828459045 pi: f64 = 3.141592653589793 @@ -12,12 +12,11 @@ eps: f64 eps = 1e-12 -n: i32 n = TypeVar("n") def zeros(n: i32) -> f64[n]: A: f64[n] - A = empty(n) + A = empty(n, dtype=float64) i: i32 for i in range(n): A[i] = 0.0 @@ -25,7 +24,7 @@ def zeros(n: i32) -> f64[n]: def ones(n: i32) -> f64[n]: A: f64[n] - A = empty(n) + A = empty(n, dtype=float64) i: i32 for i in range(n): A[i] = 1.0 @@ -126,11 +125,10 @@ def fabs(f: f64) -> f64: def fabs(b: bool) -> f64: return sqrt(b) -num: i32 num = TypeVar("num") def linspace(start: f64, stop: f64, num: i32) -> f64[num]: A: f64[num] - A = empty(num) + A = empty(num, dtype=float64) i: i32 for i in range(num): A[i] = start + (stop-start)*f64(i)/f64(num-1) diff --git a/integration_tests/test_numpy_03.py b/integration_tests/test_numpy_03.py index ea1058a19d..82faf76db4 100644 --- a/integration_tests/test_numpy_03.py +++ b/integration_tests/test_numpy_03.py @@ -1,5 +1,5 @@ -from ltypes import f64, i32 -from numpy import reshape, empty +from lpython import f64, i32 +from numpy import reshape, empty, int32, float64 def test_nd_to_1d(a: f64[:, :]): i: i32 @@ -9,8 +9,8 @@ def test_nd_to_1d(a: f64[:, :]): eps: f64 eps = 1e-12 - b: f64[256] = empty(256) - newshape: i32[1] = empty(1, dtype=int) + b: f64[256] = empty(256, dtype=float64) + newshape: i32[1] = empty(1, dtype=int32) newshape[0] = 256 b = reshape(a, newshape) for k in range(256): @@ -18,19 +18,19 @@ def test_nd_to_1d(a: f64[:, :]): j = k - i*16 assert abs(b[k] - f64(i + j) - 0.5) <= eps - c: f64[16, 16, 16] = empty((16, 16, 16)) - c = empty((16, 16, 16)) + c: f64[16, 16, 16] = empty((16, 16, 16), dtype=float64) + c = empty((16, 16, 16), dtype=float64) for i in range(16): for j in range(16): for k in range(16): c[i, j, k] = f64(i + j + k) + 0.5 - d: f64[4096] = empty(4096) - newshape1: i32[1] = empty(1, dtype=int) + d: f64[4096] = empty(4096, dtype=float64) + newshape1: i32[1] = empty(1, dtype=int32) newshape1[0] = 4096 d = reshape(c, newshape1) for l in range(4096): - i = i32(int(l/256)) + i = i32(l/256) j = (l - i*256)//16 k = (l - i*256 - j*16) assert abs(d[l] - f64(i + j + k) - 0.5) <= eps @@ -43,15 +43,15 @@ def test_1d_to_nd(d: f64[:]): eps: f64 eps = 1e-12 - b: f64[256] = empty(256) + b: f64[256] = empty(256, dtype=float64) for k in range(256): i = k//16 j = k - i*16 b[k] = f64(i + j) + 0.5 a: f64[16, 16] - a = empty((16, 16)) - newshape: i32[2] = empty(2, dtype=int) + a = empty((16, 16), dtype=float64) + newshape: i32[2] = empty(2, dtype=int32) newshape[0] = 16 newshape[1] = 16 a = reshape(b, newshape) @@ -60,8 +60,8 @@ def test_1d_to_nd(d: f64[:]): assert abs(a[i, j] - f64(i + j) - 0.5) <= eps c: f64[16, 16, 16] - c = empty((16, 16, 16)) - newshape1: i32[3] = empty(3, dtype=int) + c = empty((16, 16, 16), dtype=float64) + newshape1: i32[3] = empty(3, dtype=int32) newshape1[0] = 16 newshape1[1] = 16 newshape1[2] = 16 @@ -78,16 +78,16 @@ def test_reshape_with_argument(): l: i32 a: f64[16, 16] - a = empty((16, 16)) + a = empty((16, 16), dtype=float64) for i in range(16): for j in range(16): a[i, j] = f64(i + j) + 0.5 test_nd_to_1d(a) - d: f64[4096] = empty(4096) + d: f64[4096] = empty(4096, dtype=float64) for l in range(4096): - i = i32(int(l/256)) + i = i32(l/256) j = (l - i*256)//16 k = (l - i*256 - j*16) d[l] = f64(i + j + k) + 0.5 diff --git a/integration_tests/test_numpy_04.py b/integration_tests/test_numpy_04.py index 1225b307a7..823c573af8 100644 --- a/integration_tests/test_numpy_04.py +++ b/integration_tests/test_numpy_04.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 from numpy import array def test_array_01(): diff --git a/integration_tests/test_os.py b/integration_tests/test_os.py index b513fbbcae..20f92c342d 100644 --- a/integration_tests/test_os.py +++ b/integration_tests/test_os.py @@ -1,4 +1,4 @@ -from ltypes import i64 +from lpython import i64 from os import (open, read, close, O_RDONLY) def test(): diff --git a/integration_tests/test_package_01.py b/integration_tests/test_package_01.py new file mode 100644 index 0000000000..9ba20b210a --- /dev/null +++ b/integration_tests/test_package_01.py @@ -0,0 +1,13 @@ +from nrp import newton_raphson +from lpython import f64, i32 + + +def check(): + x0: f64 = 20.0 + c: f64 = 3.0 + maxiter: i32 = 20 + x: f64 + x = newton_raphson(x0, c, maxiter) + assert abs(x - 3.0) < 1e-5 + +check() diff --git a/integration_tests/test_params.py b/integration_tests/test_params.py new file mode 100644 index 0000000000..0748dcfd2a --- /dev/null +++ b/integration_tests/test_params.py @@ -0,0 +1,14 @@ +from lpython import i32 + +def takes_set(a: set[i32]) -> set[i32]: + return {1, 2, 3} + +def takes_dict(a: dict[i32, i32]) -> dict[i32, i32]: + return {1:1, 2:2} + +s: set[i32] = takes_set({1, 2}) + +assert len(s) == 3 + +w: dict[i32, i32] = takes_dict({1:1, 2:2}) +assert len(w) == 2 diff --git a/integration_tests/test_pass_compare.py b/integration_tests/test_pass_compare.py index f98dee1416..f076366b83 100644 --- a/integration_tests/test_pass_compare.py +++ b/integration_tests/test_pass_compare.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def f(): diff --git a/integration_tests/test_pip_import_01.py b/integration_tests/test_pip_import_01.py new file mode 100644 index 0000000000..530abb4552 --- /dev/null +++ b/integration_tests/test_pip_import_01.py @@ -0,0 +1,46 @@ +from lpynn.perceptron import init_perceptron, print_perceptron, Perceptron, train_dataset +from lpynn.utils import normalize_input_vectors +from lpython import i32, f64 + +def main0(): + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) + init_perceptron(p, 2, 0.05, 10000, 90.0) + print_perceptron(p) + print("=================================") + + input_vectors: list[list[f64]] = [[-1.0, -1.0], [-1.0, 1.0], [1.0, -1.0], [1.0, 1.0]] + outputs: list[i32] = [1, 1, 1, -1] + + normalize_input_vectors(input_vectors) + train_dataset(p, input_vectors, outputs) + print_perceptron(p) + print("=================================") + + assert p.cur_accuracy > 50.0 + assert p.epochs_cnt > 1 + assert abs(p.weights[0] - (-0.1)) < 1e-12 + assert abs(p.weights[1] - (-0.1)) < 1e-12 + assert abs(p.weights[2] - (0.1)) < 1e-12 + +def main1(): + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) + init_perceptron(p, 2, 0.05, 10000, 90.0) + print_perceptron(p) + print("=================================") + + input_vectors: list[list[f64]] = [[-1.0, -1.0], [-1.0, 1.0], [1.0, -1.0], [1.0, 1.0], [1.5, 1.0]] + outputs: list[i32] = [1, 1, -1, 1, -1] + + normalize_input_vectors(input_vectors) + train_dataset(p, input_vectors, outputs) + print_perceptron(p) + print("=================================") + + assert p.cur_accuracy > 50.0 + assert p.epochs_cnt > 1 + assert abs(p.weights[0] - (-0.22)) < 1e-12 + assert abs(p.weights[1] - (0.1)) < 1e-12 + assert abs(p.weights[2] - (0.1)) < 1e-12 + +main0() +main1() diff --git a/integration_tests/test_pkg_lnn_01.py b/integration_tests/test_pkg_lnn_01.py new file mode 100644 index 0000000000..63dcbf5ee2 --- /dev/null +++ b/integration_tests/test_pkg_lnn_01.py @@ -0,0 +1,90 @@ +from lnn.perceptron import init_perceptron, print_perceptron, Perceptron, train_dataset +from lnn.utils import normalize_input_vectors +from lpdraw import Line, Circle, Display, Clear +from lpython import i32, f64, Const +from numpy import empty, int32 + + +def compute_decision_boundary(p: Perceptron, x: f64) -> f64: + bias: f64 = p.weights[-1] + slope: f64 = (-p.weights[0] / p.weights[1]) + intercept: f64 = (-bias / p.weights[1]) + return slope * x + intercept + +def plot_graph(p: Perceptron, input_vectors: list[list[f64]], outputs: list[i32]): + Width: Const[i32] = 500 # x-axis limits [0, 499] + Height: Const[i32] = 500 # y-axis limits [0, 499] + Screen: i32[Height, Width] = empty((Height, Width), dtype=int32) + Clear(Height, Width, Screen) + + x1: f64 = 2.0 + y1: f64 = compute_decision_boundary(p, x1) + x2: f64 = -2.0 + y2: f64 = compute_decision_boundary(p, x2) + + # center the graph using the following offset + scale_offset: f64 = Width / 4 + shift_offset: f64 = Width / 2 + x1 *= scale_offset + y1 *= scale_offset + x2 *= scale_offset + y2 *= scale_offset + + # print (x1, y1, x2, y2) + Line(Height, Width, Screen, i32(x1 + shift_offset), i32(y1 + shift_offset), i32(x2 + shift_offset), i32(y2 + shift_offset)) + + i: i32 + point_size: i32 = 5 + for i in range(len(input_vectors)): + input_vectors[i][0] *= scale_offset + input_vectors[i][1] *= scale_offset + input_vectors[i][0] += shift_offset + input_vectors[i][1] += shift_offset + if outputs[i] == 1: + x: i32 = i32(input_vectors[i][0]) + y: i32 = i32(input_vectors[i][1]) + Line(Height, Width, Screen, x - point_size, y, x + point_size, y) + Line(Height, Width, Screen, x, y - point_size, x, y + point_size) + else: + Circle(Height, Width, Screen, i32(input_vectors[i][0]), i32(input_vectors[i][1]), f64(point_size)) + + Display(Height, Width, Screen) + +def main0(): + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) + init_perceptron(p, 2, 0.05, 10000, 90.0) + print_perceptron(p) + print("=================================") + + input_vectors: list[list[f64]] = [[-1.0, -1.0], [-1.0, 1.0], [1.0, -1.0], [1.0, 1.0]] + outputs: list[i32] = [1, 1, 1, -1] + + normalize_input_vectors(input_vectors) + train_dataset(p, input_vectors, outputs) + print_perceptron(p) + + assert p.cur_accuracy > 50.0 + assert p.epochs_cnt > 1 + + plot_graph(p, input_vectors, outputs) + +def main1(): + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) + init_perceptron(p, 2, 0.05, 10000, 90.0) + print_perceptron(p) + print("=================================") + + input_vectors: list[list[f64]] = [[-1.0, -1.0], [-1.0, 1.0], [1.0, -1.0], [1.0, 1.0], [1.5, 1.0]] + outputs: list[i32] = [1, 1, -1, 1, -1] + + normalize_input_vectors(input_vectors) + train_dataset(p, input_vectors, outputs) + print_perceptron(p) + + assert p.cur_accuracy > 50.0 + assert p.epochs_cnt > 1 + + plot_graph(p, input_vectors, outputs) + +main0() +main1() diff --git a/integration_tests/test_pkg_lnn_02.py b/integration_tests/test_pkg_lnn_02.py new file mode 100644 index 0000000000..c72543b179 --- /dev/null +++ b/integration_tests/test_pkg_lnn_02.py @@ -0,0 +1,89 @@ +from lnn.regression import init_perceptron, print_perceptron, Perceptron, train_dataset +from lnn.utils import normalize_input_vectors, normalize_output_vector +from lpdraw import Line, Circle, Display, Clear +from lpython import i32, f64, Const +from numpy import empty, int32 + + +def compute_decision_boundary(p: Perceptron, x: f64) -> f64: + bias: f64 = p.weights[1] + slope: f64 = p.weights[0] + intercept: f64 = bias + return slope * x + intercept + +def plot_graph(p: Perceptron, input_vectors: list[list[f64]], outputs: list[f64]): + Width: Const[i32] = 500 # x-axis limits [0, 499] + Height: Const[i32] = 500 # y-axis limits [0, 499] + Screen: i32[Height, Width] = empty((Height, Width), dtype=int32) + Clear(Height, Width, Screen) + + x1: f64 = 1.0 + y1: f64 = compute_decision_boundary(p, x1) + x2: f64 = -1.0 + y2: f64 = compute_decision_boundary(p, x2) + + # center the graph using the following offset + scale_offset: f64 = Width / 4 + shift_offset: f64 = Width / 2 + x1 *= scale_offset + y1 *= scale_offset + x2 *= scale_offset + y2 *= scale_offset + + # print (x1, y1, x2, y2) + Line(Height, Width, Screen, i32(x1 + shift_offset), i32(y1 + shift_offset), i32(x2 + shift_offset), i32(y2 + shift_offset)) + + i: i32 + point_size: i32 = 5 + for i in range(len(input_vectors)): + input_vectors[i][0] *= scale_offset + input_vectors[i][0] += shift_offset + outputs[i] *= scale_offset + outputs[i] += shift_offset + + Circle(Height, Width, Screen, i32(input_vectors[i][0]), i32(outputs[i]), f64(point_size)) + + Display(Height, Width, Screen) + +def main0(): + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) + init_perceptron(p, 1, 0.0005, 10000, 1e-16) + + input_vectors: list[list[f64]] = [[1.1], [1.3], [1.5], [2.0], [2.2], [2.9], [3.0], [3.2], [3.2], [3.7], [3.9], [4.0], [4.0], [4.1], [4.5], [4.9], [5.1], [5.3], [5.9], [6.0], [6.8], [7.1], [7.9], [8.2], [8.7], [9.0], [9.5], [9.6], [10.3], [10.5], [11.2], [11.5], [12.3], [12.9], [13.5]] + outputs: list[f64] = [39343.0, 46205.0, 37731.0, 43525.0, 39891.0, 56642.0, 60150.0, 54445.0, 64445.0, 57189.0, 63218.0, 55794.0, 56957.0, 57081.0, 61111.0, 67938.0, 66029.0, 83088.0, 81363.0, 93940.0, 91738.0, 98273.0, 101302.0, 113812.0, 109431.0, 105582.0, 116969.0, 112635.0, 122391.0, 121872.0, 127345.0, 126756.0, 128765.0, 135675.0, 139465.0] + + normalize_input_vectors(input_vectors) + normalize_output_vector(outputs) + + train_dataset(p, input_vectors, outputs) + print_perceptron(p) + + assert abs(p.weights[0] - (1.0640975812232145)) <= 1e-12 + assert abs(p.weights[1] - (0.0786977829749839)) <= 1e-12 + assert abs(p.err - (0.4735308448814293)) <= 1e-12 + assert p.epochs_cnt == 4515 + + plot_graph(p, input_vectors, outputs) + +def main1(): + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) + init_perceptron(p, 1, 0.0005, 10000, 1e-16) + + input_vectors: list[list[f64]] = [[1.0], [3.0], [7.0]] + outputs: list[f64] = [8.0, 4.0, -2.0] + + normalize_input_vectors(input_vectors) + normalize_output_vector(outputs) + + train_dataset(p, input_vectors, outputs) + print_perceptron(p) + + assert abs(p.weights[0] - (-0.9856542200697508)) <= 1e-12 + assert abs(p.weights[1] - (-0.0428446744717655)) <= 1e-12 + assert abs(p.err - 0.011428579012311327) <= 1e-12 + assert p.epochs_cnt == 10000 + + plot_graph(p, input_vectors, outputs) + +main0() +main1() diff --git a/integration_tests/test_pkg_lpconvexhull.py b/integration_tests/test_pkg_lpconvexhull.py new file mode 100644 index 0000000000..793ea696dd --- /dev/null +++ b/integration_tests/test_pkg_lpconvexhull.py @@ -0,0 +1,32 @@ +from lpython import Const, i32, f64 + +from lpdraw import Line, Circle, Clear, Display +from lpconvexhull import convex_hull +from numpy import empty, int32 + +def plot_graph(polygon: list[tuple[i32, i32]], points: list[tuple[i32, i32]]): + Width: Const[i32] = 500 # x-axis limits [0, 499] + Height: Const[i32] = 500 # y-axis limits [0, 499] + Screen: i32[Height, Width] = empty((Height, Width), dtype=int32) + Clear(Height, Width, Screen) + + i: i32 + n: i32 = len(polygon) + for i in range(n): + Line(Height, Width, Screen, polygon[i][0], polygon[i][1], polygon[(i + 1) % n][0], polygon[(i + 1) % n][1]) + + point_size: i32 = 5 + for i in range(len(points)): + Circle(Height, Width, Screen, points[i][0], points[i][1], f64(point_size)) + + Display(Height, Width, Screen) + +def main0(): + points: list[tuple[i32, i32]] = [(445, 193), (138, 28), (418, 279), (62, 438), (168, 345), (435, 325), (293, 440), (158, 94), (403, 288), (136, 278), (141, 243), (287, 313), (338, 492), (172, 78), (29, 404), (79, 377), (184, 91), (69, 324), (408, 72), (494, 1)] + convex_hull_points: list[tuple[i32, i32]] = convex_hull(points) + # print(convex_hull_points) + plot_graph(convex_hull_points, points) + + assert convex_hull_points == [(29, 404), (138, 28), (494, 1), (435, 325), (338, 492), (62, 438)] + +main0() diff --git a/integration_tests/test_pkg_lpdraw.py b/integration_tests/test_pkg_lpdraw.py new file mode 100644 index 0000000000..75fd1148da --- /dev/null +++ b/integration_tests/test_pkg_lpdraw.py @@ -0,0 +1,34 @@ +from lpdraw import Line, Circle, Clear, Display, DisplayTerminal + +from lpython import i32, TypeVar +from numpy import empty, int32 + +H = TypeVar("H") +W = TypeVar("W") + +def test_screen(H: i32, W: i32, Screen: i32[H, W]): + i: i32 + j: i32 + cnt: i32 = 0 + for i in range(H): + for j in range(W): + cnt += (Screen[i, j] - 256) + + assert cnt == -979630 + + +def main(): + Width: i32 = 100 # x-axis limits [0, 99] + Height: i32 = 40 # y-axis limits [0, 39] + Screen: i32[40, 100] = empty((40, 100), dtype=int32) + + Clear(Height, Width, Screen) + Line(Height, Width, Screen, 2, 4, 99, 11) + Line(Height, Width, Screen, 0, 39, 49, 0) + Circle(Height, Width, Screen, 52, 20, 6.0) + Display(Height, Width, Screen) + DisplayTerminal(Height, Width, Screen) + + test_screen(Height, Width, Screen) + +main() diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py index d1cded5add..0cf91c7870 100644 --- a/integration_tests/test_random.py +++ b/integration_tests/test_random.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 import random @@ -52,6 +52,35 @@ def test_weibullvariate(): r = random.weibullvariate(-5.6, 1.2) print(r) +def test_seed(): + random.seed() + t6: f64 = random.random() + random.seed(123) + t1: f64 + t1 = random.random() + random.seed(321) + t2: f64 + t2 = random.random() + random.seed(123) + t3: f64 + t3 = random.random() + random.seed(0) + t4: f64 + t4 = random.random() + random.seed(0) + t5: f64 + t5 = random.random() + random.seed() + t7: f64 = random.random() + + print(t1, t2, t3, t4, t5, t6, t7) + assert t1 != t2 + assert t1 == t3 + assert t1 != t4 + assert t1 != t5 + assert t4 == t5 + # assert t6 != t7 + def check(): test_random() test_randrange() @@ -60,5 +89,6 @@ def check(): test_paretovariate() test_expovariate() test_weibullvariate() + test_seed() check() diff --git a/integration_tests/test_random_02.py b/integration_tests/test_random_02.py new file mode 100644 index 0000000000..560dfe8cd6 --- /dev/null +++ b/integration_tests/test_random_02.py @@ -0,0 +1,21 @@ +from lpython import i32, f64 +import random + +def test_seed(): + """test the distribution of random""" + num_samples:i32 = 100000 + bins: list[i32] = [0]*10 + _ : i32 + for _ in range(num_samples): + val: f64 = random.random() + assert val >= 0.0 and val < 1.0 # value out of range + bins[i32(val * 10.0)] += 1 # increment the appropriate bin + + # Check that no bin has significantly more or fewer values than expected + expected_bin_count:i32 = i32(num_samples / 10) + count : i32 + for count in bins: + blas: f64 = f64(abs(count - expected_bin_count)) + assert blas < f64(expected_bin_count) * 0.05 # allow 5% deviation + +test_seed() diff --git a/integration_tests/test_set_add.py b/integration_tests/test_set_add.py new file mode 100644 index 0000000000..699b1cfa58 --- /dev/null +++ b/integration_tests/test_set_add.py @@ -0,0 +1,34 @@ +from lpython import i32 + +def test_set_add(): + s1: set[i32] + s2: set[tuple[i32, tuple[i32, i32], str]] + s3: set[str] + st1: str + i: i32 + j: i32 + + s1 = {0} + s2 = {(0, (1, 2), 'a')} + for i in range(20): + j = i % 10 + s1.add(j) + s2.add((j, (j + 1, j + 2), 'a')) + assert len(s1) == len(s2) + if i < 10: + assert len(s1) == i + 1 + else: + assert len(s1) == 10 + + st1 = 'a' + s3 = {st1} + for i in range(20): + s3.add(st1) + if i < 10: + if i > 0: + assert len(s3) == i + st1 += 'a' + else: + assert len(s3) == 10 + +test_set_add() diff --git a/integration_tests/test_set_clear.py b/integration_tests/test_set_clear.py new file mode 100644 index 0000000000..871e2c2bf7 --- /dev/null +++ b/integration_tests/test_set_clear.py @@ -0,0 +1,21 @@ +def test_clear(): + a: set[i32] = {1, 2} + + a.clear() + a.add(3) + + assert len(a) == 1 + a.remove(3) + assert len(a) == 0 + + b: set[str] = {'a', 'b'} + + b.clear() + b.add('c') + + assert len(b) == 1 + b.remove('c') + assert len(b) == 0 + + +test_clear() diff --git a/integration_tests/test_set_constructor.py b/integration_tests/test_set_constructor.py new file mode 100644 index 0000000000..497819dbb7 --- /dev/null +++ b/integration_tests/test_set_constructor.py @@ -0,0 +1,17 @@ +def test_empty_set(): + a: set[i32] = set() + assert len(a) == 0 + a.add(2) + a.remove(2) + a.add(3) + assert a.pop() == 3 + + b: set[str] = set() + + assert len(b) == 0 + b.add('a') + b.remove('a') + b.add('b') + assert b.pop() == 3 + +test_empty_set() diff --git a/integration_tests/test_set_discard.py b/integration_tests/test_set_discard.py new file mode 100644 index 0000000000..730abaff7d --- /dev/null +++ b/integration_tests/test_set_discard.py @@ -0,0 +1,48 @@ +from lpython import i32 + +def test_set_discard(): + s1: set[i32] + s2: set[tuple[i32, tuple[i32, i32], str]] + s3: set[str] + st1: str + i: i32 + j: i32 + k: i32 + + for k in range(2): + s1 = {0} + s2 = {(0, (1, 2), "a")} + for i in range(20): + j = i % 10 + s1.add(j) + s2.add((j, (j + 1, j + 2), "a")) + + for i in range(10): + s1.discard(i) + s2.discard((i, (i + 1, i + 2), "a")) + assert len(s1) == 10 - 1 - i + assert len(s1) == len(s2) + + st1 = "a" + s3 = {st1} + for i in range(20): + s3.add(st1) + if i < 10: + if i > 0: + st1 += "a" + + st1 = "a" + for i in range(10): + s3.discard(st1) + assert len(s3) == 10 - 1 - i + if i < 10: + st1 += "a" + + for i in range(20): + s1.add(i) + if i % 2 == 0: + s1.discard(i) + assert len(s1) == (i + 1) // 2 + + +test_set_discard() diff --git a/integration_tests/test_set_from_list.py b/integration_tests/test_set_from_list.py new file mode 100644 index 0000000000..e06b4e40c1 --- /dev/null +++ b/integration_tests/test_set_from_list.py @@ -0,0 +1,14 @@ +from lpython import i32 + + +def test_set(): + s: set[i32] + s = set([1, 2, 2, 2, -1, 1, 1, 3]) + assert len(s) == 4 + + s2: set[str] + s2 = set(["a", "b", "b", "abc", "a"]) + assert len(s2) == 3 + + +test_set() diff --git a/integration_tests/test_set_len.py b/integration_tests/test_set_len.py new file mode 100644 index 0000000000..2b07c2d1ac --- /dev/null +++ b/integration_tests/test_set_len.py @@ -0,0 +1,11 @@ +from lpython import i32 + +def test_set(): + s: set[i32] + s = {1, 2, 22, 2, -1, 1} + assert len(s2) == 4 + s2: set[str] + s2 = {'a', 'b', 'cd', 'b', 'abc', 'a'} + assert len(s2) == 4 + +test_set() diff --git a/integration_tests/test_set_pop.py b/integration_tests/test_set_pop.py new file mode 100644 index 0000000000..af4500e236 --- /dev/null +++ b/integration_tests/test_set_pop.py @@ -0,0 +1,26 @@ +def set_pop_str(): + s: set[str] = {'a', 'b', 'c'} + + assert s.pop() in {'a', 'b', 'c'} + assert len(s) == 2 + assert s.pop() in {'a', 'b', 'c'} + assert s.pop() in {'a', 'b', 'c'} + assert len(s) == 0 + + s.add('d') + assert s.pop() == 'd' + +def set_pop_int(): + s: set[i32] = {1, 2, 3} + + assert s.pop() in {1, 2, 3} + assert len(s) == 2 + assert s.pop() in {1, 2, 3} + assert s.pop() in {1, 2, 3} + assert len(s) == 0 + + s.add(4) + assert s.pop() == 4 + +set_pop_str() +set_pop_int() diff --git a/integration_tests/test_set_remove.py b/integration_tests/test_set_remove.py new file mode 100644 index 0000000000..ca93ec0a80 --- /dev/null +++ b/integration_tests/test_set_remove.py @@ -0,0 +1,47 @@ +from lpython import i32 + +def test_set_add(): + s1: set[i32] + s2: set[tuple[i32, tuple[i32, i32], str]] + s3: set[str] + st1: str + i: i32 + j: i32 + k: i32 + + for k in range(2): + s1 = {0} + s2 = {(0, (1, 2), 'a')} + for i in range(20): + j = i % 10 + s1.add(j) + s2.add((j, (j + 1, j + 2), 'a')) + + for i in range(10): + s1.remove(i) + s2.remove((i, (i + 1, i + 2), 'a')) + # assert len(s1) == 10 - 1 - i + # assert len(s1) == len(s2) + + st1 = 'a' + s3 = {st1} + for i in range(20): + s3.add(st1) + if i < 10: + if i > 0: + st1 += 'a' + + st1 = 'a' + for i in range(10): + s3.remove(st1) + assert len(s3) == 10 - 1 - i + if i < 10: + st1 += 'a' + + for i in range(20): + s1.add(i) + if i % 2 == 0: + s1.remove(i) + assert len(s1) == (i + 1) // 2 + +test_set_add() \ No newline at end of file diff --git a/integration_tests/test_statistics.py b/integration_tests/test_statistics.py deleted file mode 100644 index 175bbe643b..0000000000 --- a/integration_tests/test_statistics.py +++ /dev/null @@ -1,231 +0,0 @@ -from statistics import (mean, fmean, geometric_mean, harmonic_mean, variance, - stdev, pvariance, pstdev, correlation, covariance, - linear_regression, mode) -from ltypes import i32, f64, i64, f32 - - -eps: f64 -eps = 1e-12 - - -def test_mean(): - b: list[i32] - b = [9, 4, 10] - j: f64 - j = mean(b) - assert abs(j - 7.666666666666667) < eps - - c: list[f64] - c = [2.0, 3.1, 11.1] - k: f64 - k = mean(c) - assert abs(k - 5.4) < eps - - d: list[i32] - d = [1, 3, 11] - l: f64 - l = mean(d) - assert abs(l - 5.0) < eps - -def test_fmean(): - a: list[i32] - a = [9, 4, 10] - j: f64 - j = fmean(a) - assert abs(j - 7.666666666666667) < eps - - b: list[f64] - b = [-1.9, -13.8, -6.0, 4.2, 5.9, 9.1] - k: f64 - k = fmean(b) - assert abs(k + 0.41666666666666674) < eps - - -def test_geometric_mean(): - c: list[i32] - c = [1,2,3] - k: f64 - k = geometric_mean(c) - assert abs(k - 1.8171205928321397) < eps - - d: list[f64] - d = [1.1, 3.4, 17.982, 11.8] - l: f64 - l = geometric_mean(d) - assert abs(l - 5.307596520524432) < eps - -def test_harmonic_mean(): - c: list[i32] - c = [9,2,46] - k: f64 - k = harmonic_mean(c) - assert abs(k - 4.740458015267175) < eps - - d: list[i32] - d = [9, 0, 46] - l: f64 - l = harmonic_mean(d) - assert l == 0.0 - - e: list[f64] - e = [1.1, 3.4, 17.982, 11.8] - f: f64 - f = harmonic_mean(e) - assert abs(f - 2.977152988015106) < eps - - -def test_variance(): - a: list[i32] - a = [1, 2, 5, 4, 8, 9, 12] - j: f64 - j = variance(a) - assert abs(j - 15.80952380952381) < eps - - b: list[f64] - b = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] - k: f64 - k = variance(b) - assert abs(k - 0.40924) < eps - -def test_stdev(): - a: list[i32] - a = [1, 2, 3, 4, 5] - j: f64 - j = stdev(a) - assert abs(j - 1.5811388300841898) < eps - - b: list[f64] - b = [1.23, 1.45, 2.1, 2.2, 1.9] - k: f64 - k = stdev(b) - assert abs(k - 0.41967844833872525) < eps - -def test_pvariance(): - a: list[i32] - a = [1, 2, 5, 4, 8, 9, 12] - j: f64 - j = pvariance(a) - assert abs(j - 13.551020408163266) < eps - - b: list[f64] - b = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] - k: f64 - k = pvariance(b) - assert abs(k - 0.34103333333333335) < eps - -def test_pstdev(): - a: list[i32] - a = [1, 2, 3, 4, 5] - j: f64 - j = pstdev(a) - assert abs(j - 1.4142135623730951) < eps - - b: list[f64] - b = [1.23, 1.45, 2.1, 2.2, 1.9] - k: f64 - k = pstdev(b) - assert abs(k - 0.37537181567080935) < eps - - -def test_covariance(): - a: list[i32] - a = [1, 2, 3, 4, 5, 6, 7, 8, 9] - b: list[i32] - b = [1, 2, 3, 1, 2, 3, 1, 2, 3] - j: f64 - j = covariance(a, b) - assert abs(j - 0.75) < eps - - c: list[f64] - c = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] - d: list[f64] - d = [9.4, 1.23, 2.63, 22.4, 1.9, 13.98] - k: f64 - k = covariance(c, d) - assert abs(k + 0.24955999999999934) < eps - - -def test_correlation(): - a: list[i32] - a = [11, 2, 7, 4, 15, 6, 10, 8, 9, 1, 11, 5, 13, 6, 15] - b: list[i32] - b = [2, 5, 17, 6, 10, 8, 13, 4, 6, 9, 11, 2, 5, 4, 7] - - j: f64 - j = correlation(a, b) - assert abs(j - 0.11521487988958108) < eps - - c: list[f64] - c = [2.0, 23.0, 24.55, 64.436, 5403.23] - d: list[f64] - d = [26.9, 75.6, 34.06, 356.89, 759.26] - - j = correlation(c, c) - assert abs(j - 1.0) < eps - - j = correlation(c, d) - assert abs(j - 0.9057925526720572) < eps - -def test_linear_regression(): - c: list[f64] - c = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] - d: list[f64] - d = [9.4, 1.23, 2.63, 22.4, 1.9, 13.98] - - slope: f64 - intercept: f64 - slope, intercept = linear_regression(c, d) - - assert abs(slope + 0.6098133124816717) < eps - assert abs(intercept - 9.992570618707845) < eps - - a: list[i32] - b: list[i32] - a = [12, 24, 2, 1, 43, 53, 23] - b = [2, 13, 14, 63, 49, 7, 3] - - slope, intercept = linear_regression(a, b) - - assert abs(slope + 0.18514007308160782) < eps - assert abs(intercept - 25.750304506699152) < eps - -def test_mode(): - a: list[i32] - a = [3, 1, 12, 4, 0] - i: i32 - i = mode(a) - assert i == 3 - - b: list[i32] - b = [4, 2, 4, 4, 2, 3, 5] - j: i32 - j = mode(b) - assert j == 4 - - c: list[i32] - c = [2, 3, 4, 1, 2, 4, 5] - k: i32 - k = mode(c) - assert k == 2 - - d: list[i32] - d = [-1, 2, -3, -5, -3, -1, 4, -2, 4, -5, -3, 4, -3] - k = mode(d) - assert k == -3 - - -def check(): - test_mean() - test_geometric_mean() - test_harmonic_mean() - test_fmean() - test_variance() - test_stdev() - test_pvariance() - test_pstdev() - test_linear_regression() - test_correlation() - test_covariance() - test_mode() - -check() diff --git a/integration_tests/test_statistics_01.py b/integration_tests/test_statistics_01.py new file mode 100644 index 0000000000..3eeddeed6a --- /dev/null +++ b/integration_tests/test_statistics_01.py @@ -0,0 +1,169 @@ +from statistics import (mean, fmean, geometric_mean, harmonic_mean, variance, + stdev, pvariance, pstdev, mode) +from lpython import i32, f64, i64 + + +eps: f64 +eps = 1e-12 + + +def test_mean(): + b: list[i32] + b = [9, 4, 10] + j: f64 + j = mean(b) + assert abs(j - 7.666666666666667) < eps + + c: list[f64] + c = [2.0, 3.1, 11.1] + k: f64 + k = mean(c) + assert abs(k - 5.4) < eps + + d: list[i32] + d = [1, 3, 11] + l: f64 + l = mean(d) + assert abs(l - 5.0) < eps + +def test_fmean(): + a: list[i32] + a = [9, 4, 10] + j: f64 + j = fmean(a) + assert abs(j - 7.666666666666667) < eps + + b: list[f64] + b = [-1.9, -13.8, -6.0, 4.2, 5.9, 9.1] + k: f64 + k = fmean(b) + assert abs(k + 0.41666666666666674) < eps + + +def test_geometric_mean(): + c: list[i32] + c = [1,2,3] + k: f64 + k = geometric_mean(c) + assert abs(k - 1.8171205928321397) < eps + + d: list[f64] + d = [1.1, 3.4, 17.982, 11.8] + l: f64 + l = geometric_mean(d) + assert abs(l - 5.307596520524432) < eps + +def test_harmonic_mean(): + c: list[i32] + c = [9,2,46] + k: f64 + k = harmonic_mean(c) + assert abs(k - 4.740458015267175) < eps + + d: list[i32] + d = [9, 0, 46] + l: f64 + l = harmonic_mean(d) + assert l == 0.0 + + e: list[f64] + e = [1.1, 3.4, 17.982, 11.8] + f: f64 + f = harmonic_mean(e) + assert abs(f - 2.977152988015106) < eps + + +def test_variance(): + a: list[i32] + a = [1, 2, 5, 4, 8, 9, 12] + j: f64 + j = variance(a) + assert abs(j - 15.80952380952381) < eps + + b: list[f64] + b = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] + k: f64 + k = variance(b) + assert abs(k - 0.40924) < eps + +def test_stdev(): + a: list[i32] + a = [1, 2, 3, 4, 5] + j: f64 + j = stdev(a) + assert abs(j - 1.5811388300841898) < eps + + b: list[f64] + b = [1.23, 1.45, 2.1, 2.2, 1.9] + k: f64 + k = stdev(b) + assert abs(k - 0.41967844833872525) < eps + +def test_pvariance(): + a: list[i32] + a = [1, 2, 5, 4, 8, 9, 12] + j: f64 + j = pvariance(a) + assert abs(j - 13.551020408163266) < eps + + b: list[f64] + b = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] + k: f64 + k = pvariance(b) + assert abs(k - 0.34103333333333335) < eps + +def test_pstdev(): + a: list[i32] + a = [1, 2, 3, 4, 5] + j: f64 + j = pstdev(a) + assert abs(j - 1.4142135623730951) < eps + + b: list[f64] + b = [1.23, 1.45, 2.1, 2.2, 1.9] + k: f64 + k = pstdev(b) + assert abs(k - 0.37537181567080935) < eps + +def test_mode(): + a: list[i32] + a = [3, 1, 12, 4, 0] + i: i32 + i = mode(a) + assert i == 3 + + b: list[i32] + b = [4, 2, 4, 4, 2, 3, 5] + j: i32 + j = mode(b) + assert j == 4 + + c: list[i32] + c = [2, 3, 4, 1, 2, 4, 5] + k: i32 + k = mode(c) + assert k == 2 + + d: list[i32] + d = [-1, 2, -3, -5, -3, -1, 4, -2, 4, -5, -3, 4, -3] + k = mode(d) + assert k == -3 + + e: list[i64] + e = [i64(-1), i64(2), i64(-3), i64(-5), i64(-3), i64(-1), i64(4), i64(-2), i64(4), i64(-5), i64(-3), i64(4), i64(-3)] + l: i64 = mode(e) + assert l == i64(-3) + + +def check(): + test_mean() + test_geometric_mean() + test_harmonic_mean() + test_fmean() + test_variance() + test_stdev() + test_pvariance() + test_pstdev() + test_mode() + +check() diff --git a/integration_tests/test_statistics_02.py b/integration_tests/test_statistics_02.py new file mode 100644 index 0000000000..0930c095a5 --- /dev/null +++ b/integration_tests/test_statistics_02.py @@ -0,0 +1,77 @@ +from statistics import (covariance, correlation, + linear_regression) +from lpython import i32, f64 + + +eps: f64 +eps = 1e-12 + +def test_covariance(): + a: list[i32] + a = [1, 2, 3, 4, 5, 6, 7, 8, 9] + b: list[i32] + b = [1, 2, 3, 1, 2, 3, 1, 2, 3] + j: f64 + j = covariance(a, b) + assert abs(j - 0.75) < eps + + c: list[f64] + c = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] + d: list[f64] + d = [9.4, 1.23, 2.63, 22.4, 1.9, 13.98] + k: f64 + k = covariance(c, d) + assert abs(k + 0.24955999999999934) < eps + + +def test_correlation(): + a: list[i32] + a = [11, 2, 7, 4, 15, 6, 10, 8, 9, 1, 11, 5, 13, 6, 15] + b: list[i32] + b = [2, 5, 17, 6, 10, 8, 13, 4, 6, 9, 11, 2, 5, 4, 7] + + j: f64 + j = correlation(a, b) + assert abs(j - 0.11521487988958108) < eps + + c: list[f64] + c = [2.0, 23.0, 24.55, 64.436, 5403.23] + d: list[f64] + d = [26.9, 75.6, 34.06, 356.89, 759.26] + + j = correlation(c, c) + assert abs(j - 1.0) < eps + + j = correlation(c, d) + assert abs(j - 0.9057925526720572) < eps + +def test_linear_regression(): + c: list[f64] + c = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] + d: list[f64] + d = [9.4, 1.23, 2.63, 22.4, 1.9, 13.98] + + slope: f64 + intercept: f64 + slope, intercept = linear_regression(c, d) + + assert abs(slope + 0.6098133124816717) < eps + assert abs(intercept - 9.992570618707845) < eps + + a: list[i32] + b: list[i32] + a = [12, 24, 2, 1, 43, 53, 23] + b = [2, 13, 14, 63, 49, 7, 3] + + slope, intercept = linear_regression(a, b) + + assert abs(slope + 0.18514007308160782) < eps + assert abs(intercept - 25.750304506699152) < eps + + +def check(): + test_linear_regression() + test_correlation() + test_covariance() + +check() diff --git a/integration_tests/test_str_01.py b/integration_tests/test_str_01.py index 014b798fca..0a65e8d075 100644 --- a/integration_tests/test_str_01.py +++ b/integration_tests/test_str_01.py @@ -1,3 +1,5 @@ +from lpython import i32 + def f(): x: str x = "ok" @@ -37,17 +39,161 @@ def test_str_slice(): # TODO: # assert a[0:5:-1] == "" + +def test_str_title(): + a: str = "hello world" + b: str = "hj'kl" + c: str = "hELlo wOrlD" + d: str = "{Hel1o}world" + res: str = a.title() + res2: str = b.title() + res3: str = c.title() + res4: str = d.title() + assert res == "Hello World" + assert res2 == "Hj'Kl" + assert res3 == "Hello World" + assert res4 == "{Hel1O}World" + def test_str_repeat(): a: str a = "Xyz" assert a*3 == "XyzXyzXyz" assert a*2*3 == "XyzXyzXyzXyzXyzXyz" assert 3*a*3 == "XyzXyzXyzXyzXyzXyzXyzXyzXyz" - assert a*-1 == "" + b: str = a * -1 + assert b == "" + assert len(a*(10**6)) == (3 * 10 ** 6) + + # string repeat with a non-constant integer + s: str = "#" + n: i32 = 5 + + assert s * n == "#####" + assert n * s == "#####" + + assert "@" * n == "@@@@@" + assert "@#$%" * n == "@#$%@#$%@#$%@#$%@#$%" + + s = "@#$%" + assert n * s == "@#$%@#$%@#$%@#$%@#$%" + + n = 10 ** 6 + assert len(s * n) == (4 * 10 ** 6) + + s = "$" + m: i32 = 2 + n = 5 + t: str = s * m * n + assert t == "$$$$$$$$$$" + assert s * m * 2 == "$$$$" + assert 2 * (m + n) * s == "$$$$$$$$$$$$$$" + + t = 2 * (m + n) * "abc-" + assert t == "abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-" + + +# def test_str_join(): +# a: str +# a = "," +# p:list[str] = ["a","b"] +# res:str = a.join(p) +# assert res == "a,b" +# +# def test_str_join2(): +# a: str +# a = "**" +# p:list[str] = ["a","b"] +# res:str = a.join(p) +# assert res == "a**b" +# +# def test_str_join_empty_str(): +# a: str +# a = "" +# p:list[str] = ["a","b"] +# res:str = a.join(p) +# assert res == "ab" +# +# def test_str_join_empty_list(): +# a: str +# a = "ab" +# p:list[str] = [] +# res:str = a.join(p) +# assert res == "" +# +# def test_constant_str_subscript(): +# assert "abc"[2] == "c" +# assert "abc"[:2] == "ab" +# +# def test_str_split(): +# a: str = "1,2,3" +# b: str = "1,2,,3," +# c: str = "1and2and3" +# d: str = "1 2 3" +# e: str = " 1 2 3 " +# f: str = "123" +# res: list[str] = a.split(",") +# res1: list[str] = b.split(",") +# res2: list[str] = c.split("and") +# res3: list[str] = d.split() +# res4: list[str] = e.split() +# res5: list[str] = f.split(" ") +# # res6: list[str] = "".split(" ") +# assert res == ["1", "2", "3"] +# assert res1 == ["1", "2", "", "3", ""] +# assert res2 == ["1", "2", "3"] +# assert res3 == ["1", "2", "3"] +# assert res4 == ["1", "2", "3"] +# assert res5 == ["123"] +# # assert res6 == [""] + +def test_str_replace(): + x: str = "abc" + a: str = "zzaaabracadabra" + print(a.replace("a","")) + print(a.replace("","")) + print(a.replace("a","b")) + print(a.replace("e","a")) + print(a.replace("ab","ba")) + print(a.replace("c","z")) + print(a.replace("zza","yo")) + print(a.replace("a","b",0)) + print(a.replace("a","b",1)) + print(a.replace("a","b",2)) + print(a.replace("a","b",2)) + print(a.replace("a","b",3)) + print(a.replace("a","b",4)) + print(a.replace("a","b",5)) + print(a.replace("a","b",6)) + print(a.replace("a","b",7)) + print(a.replace("a","b",8)) + print(a.replace("a","b",9)) + print(a.replace("b","k",1)) + print(a.replace("b","k",2)) + print(a.replace("zza","yo",2)) + print(x.replace("", ",")) + assert a.replace("a","") == "zzbrcdbr" + assert a.replace("","") == "zzaaabracadabra" + assert a.replace("a","b") == "zzbbbbrbcbdbbrb" + assert a.replace("e","a") == "zzaaabracadabra" + assert a.replace("ab","ba") == "zzaabaracadbara" + assert a.replace("c","z") == "zzaaabrazadabra" + assert a.replace("zza","yo") == "yoaabracadabra" + assert a.replace("a","b",0) == "zzaaabracadabra" + assert a.replace("a","b",1) == "zzbaabracadabra" + assert a.replace("a","b",2) == "zzbbabracadabra" + assert a.replace("a","b",2) == "zzbbabracadabra" + assert a.replace("a","b",3) == "zzbbbbracadabra" + assert a.replace("a","b",4) == "zzbbbbrbcadabra" + assert a.replace("a","b",5) == "zzbbbbrbcbdabra" + assert a.replace("a","b",6) == "zzbbbbrbcbdbbra" + assert a.replace("a","b",7) == "zzbbbbrbcbdbbrb" + assert a.replace("a","b",8) == "zzbbbbrbcbdbbrb" + assert a.replace("a","b",9) == "zzbbbbrbcbdbbrb" + assert a.replace("b","k",1) == "zzaaakracadabra" + assert a.replace("b","k",2) == "zzaaakracadakra" + assert a.replace("zza","yo",2) == "yoaabracadabra" + assert x.replace("", ",") == ",a,b,c," -def test_constant_str_subscript(): - assert "abc"[2] == "c" - assert "abc"[:2] == "ab" def check(): f() @@ -55,6 +201,13 @@ def check(): test_str_index() test_str_slice() test_str_repeat() - test_constant_str_subscript() +# test_str_join() +# test_str_join2() +# test_str_join_empty_str() +# test_str_join_empty_list() +# test_constant_str_subscript() +# test_str_title() +# test_str_split() + test_str_replace() check() diff --git a/integration_tests/test_str_03.py b/integration_tests/test_str_03.py index 891b5fb4bc..5dd91d3d35 100644 --- a/integration_tests/test_str_03.py +++ b/integration_tests/test_str_03.py @@ -1,10 +1,18 @@ -from ltypes import i8, i16, i32, i64 +from lpython import i8, i16, i32, i64 def test_new_line(): print("abc\n") print("\ndef") print("x\nyz") +def test_escape_sequences(): + print('I said \'Wow\' ') + print("I said \"hi\" ") + print("I said \\\"hi\" ") + print('I said \'\\\'hi\\''hey\' ') + print('a''b') + print("a" "b") + def test_int(): i: i8 = i8(1) j: i16 = i16(2) @@ -23,5 +31,6 @@ def test_issue_1124(): test_new_line() +test_escape_sequences() test_int() test_issue_1124() diff --git a/integration_tests/test_str_04.py b/integration_tests/test_str_04.py new file mode 100644 index 0000000000..c0ede7991f --- /dev/null +++ b/integration_tests/test_str_04.py @@ -0,0 +1,11 @@ +def main0(): + x: str + x = "abcdefghijkl" + print(len(x)) + assert len(x) == 12 + + y: str = "123" + print(len(y)) + assert len(y) == 3 + +main0() diff --git a/integration_tests/test_str_05.py b/integration_tests/test_str_05.py new file mode 100644 index 0000000000..e3eef630b2 --- /dev/null +++ b/integration_tests/test_str_05.py @@ -0,0 +1,12 @@ +def main0(): + x: str + x = "Hello, World" + y: str + y = "o" + assert x.count(y) == 2 + y = "" + assert x.count(y) == len(x) + 1 + y = "Hello," + assert x.count(y) == 1 + +main0() diff --git a/integration_tests/test_str_06.py b/integration_tests/test_str_06.py new file mode 100644 index 0000000000..8df130521d --- /dev/null +++ b/integration_tests/test_str_06.py @@ -0,0 +1,11 @@ +def main0(): + x: str + x = "Hello, World" + + assert "Hello" in x + assert "," in x + assert "rld" in x + + assert "Hello" not in "World" + +main0() diff --git a/integration_tests/test_str_attributes.py b/integration_tests/test_str_attributes.py old mode 100644 new mode 100755 index cfe4d91bfb..b8b24cf8fa --- a/integration_tests/test_str_attributes.py +++ b/integration_tests/test_str_attributes.py @@ -1,13 +1,20 @@ def capitalize(): s: str s = "tom and jerry" + print(s.capitalize()) assert s.capitalize() == "Tom and jerry" s = "12wddd" + print(s) assert s.capitalize() == s s = " tom and jerry" + print(s.capitalize()) assert s.capitalize() == s assert "empty string" .capitalize() == "Empty string" assert "".capitalize() == "" + assert "lPyThOn".capitalize() == "Lpython" + x: str + x = "lPyThOn" + assert x.capitalize() == "Lpython" def lower(): @@ -18,6 +25,14 @@ def lower(): assert "".lower() == "" +def upper(): + s: str + s = "AaaaAABBbbbbBB!@12223BN" + assert s.upper() == "AAAAAABBBBBBBB!@12223BN" + assert "DDd12Vv".upper() == "DDD12VV" + assert "".upper() == "" + + def strip(): s: str s = " AASAsaSas " @@ -59,6 +74,29 @@ def find(): assert s2.find("we") == -1 assert "".find("") == 0 +def count(): + s: str + sub: str + s = "ABC ABCDAB ABCDABCDABDE" + sub = "ABC" + print(s.count(sub), s.count("ABC")) + assert s.count(sub) == 4 + assert s.count("ABC") == 4 + + sub = "AB" + print(s.count(sub), s.count("AB")) + assert s.count(sub) == 6 + assert s.count("AB") == 6 + + sub = "ABC" + print("ABC ABCDAB ABCDABCDABDE".count(sub), "ABC ABCDAB ABCDABCDABDE".count("ABC")) + assert "ABC ABCDAB ABCDABCDABDE".count(sub) == 4 + assert "ABC ABCDAB ABCDABCDABDE".count("ABC") == 4 + + sub = "AB" + assert "ABC ABCDAB ABCDABCDABDE".count(sub) == 6 + assert "ABC ABCDAB ABCDABCDABDE".count("AB") == 6 + def startswith(): s: str @@ -79,12 +117,408 @@ def startswith(): assert "".startswith("ok") == False +def endswith(): + + # The following test suite fulfils the control flow graph coverage + # in terms of Statement Coverage and Branch Coverage associated with endwith() functionality. + + # Case 1: When string is constant and suffix is also constant + assert "".endswith("") == True + assert "".endswith(" ") == False + assert "".endswith("%") == False + assert "".endswith("a1234PT#$") == False + assert "".endswith("blah blah") == False + assert " rendezvous 5:30 ".endswith("") == True + assert " rendezvous 5:30 ".endswith(" ") == True + assert " rendezvous 5:30 ".endswith(" 5:30 ") == True + assert " rendezvous 5:30 ".endswith("apple") == False + assert "two plus".endswith("longer than string") == False + + # Case 2: When string is constant and suffix is variable + suffix: str + suffix = "" + assert "".endswith(suffix) == True + suffix = " " + assert "".endswith(suffix) == False + suffix = "5:30 " + assert " rendezvous 5:30 ".endswith(suffix) == True + suffix = "" + assert " rendezvous 5:30 ".endswith(suffix) == True + suffix = "apple" + assert " rendezvous 5:30 ".endswith(suffix) == False + suffix = "longer than string" + assert "two plus".endswith(suffix) == False + + # Case 3: When string is variable and suffix is either constant or variable + s: str + s = "" + assert s.endswith("") == True + assert s.endswith("apple") == False + assert s.endswith(" ") == False + assert s.endswith(suffix) == False + + s = " rendezvous 5 " + assert s.endswith(" $3324") == False + assert s.endswith("5 ") == True + assert s.endswith(s) == True + suffix = "vous 5 " + assert s.endswith(suffix) == True + suffix = "apple" + assert s.endswith(suffix) == False + + +def partition(): + + # Note: Both string or seperator cannot be empty + # Case 1: When string is constant and seperator is also constant + assert " ".partition(" ") == ("", " ", " ") + assert "apple mango".partition(" ") == ("apple", " ", "mango") + assert "applemango".partition("afdnjkfsn") == ("applemango", "", "") + assert "applemango".partition("an") == ("applem", "an", "go") + assert "applemango".partition("mango") == ("apple", "mango", "") + assert "applemango".partition("applemango") == ("", "applemango", "") + assert "applemango".partition("ppleman") == ("a", "ppleman", "go") + assert "applemango".partition("pplt") == ("applemango", "", "") + + # Case 2: When string is constant and seperator is variable + seperator: str + seperator = " " + assert " ".partition(seperator) == ("", " ", " ") + seperator = " " + assert "apple mango".partition(seperator) == ("apple", " ", "mango") + seperator = "5:30 " + assert " rendezvous 5:30 ".partition( + seperator) == (" rendezvous ", "5:30 ", "") + seperator = "^&" + assert "@#$%^&*()#!".partition(seperator) == ("@#$%", "^&", "*()#!") + seperator = "daddada " + assert " rendezvous 5:30 ".partition( + seperator) == (" rendezvous 5:30 ", "", "") + seperator = "longer than string" + assert "two plus".partition(seperator) == ("two plus", "", "") + + # Case 3: When string is variable and seperator is either constant or variable + s: str + s = "tomorrow" + assert s.partition("apple") == ("tomorrow", "", "") + assert s.partition("rr") == ("tomo", "rr", "ow") + assert s.partition(seperator) == ("tomorrow", "", "") + + s = "rendezvous 5" + assert s.partition(" ") == ("rendezvous", " ", "5") + assert s.partition("5") == ("rendezvous ", "5", "") + assert s.partition(s) == ("", "rendezvous 5", "") + seperator = "vous " + assert s.partition(seperator) == ("rendez", "vous ", "5") + seperator = "apple" + assert s.partition(seperator) == ("rendezvous 5", "", "") + + +def is_lower(): + # Case 1: When constant string is present + assert "".islower() == False + assert "APPLE".islower() == False + assert "4432632479".islower() == False + assert "%#$#$#32a".islower() == True + assert "apple".islower() == True + assert "apple is a fruit".islower() == True + + # Case 2: When variable string is present + s: str + s = "APPLE" + assert s.islower() == False + s = "238734587" + assert s.islower() == False + s = "%#$#$#32a" + assert s.islower() == True + s = "apple" + assert s.islower() == True + s = "apple is a fruit" + assert s.islower() == True + + +def is_upper(): + # Case 1: When constant string is present + assert "".isupper() == False + assert "apple".isupper() == False + assert "4432632479".isupper() == False + assert "%#$#$#32A".isupper() == True + assert "APPLE".isupper() == True + assert "APPLE IS A FRUIT".isupper() == True + + # Case 2: When variable string is present + s: str + s = "apple" + assert s.isupper() == False + s = "238734587" + assert s.isupper() == False + s = "%#$#$#32A" + assert s.isupper() == True + s = "APPLE" + assert s.isupper() == True + s = "APPLE IS A FRUIT" + assert s.isupper() == True + + +def is_decimal(): + # Case 1: When constant string is present + assert "".isdecimal() == False + assert "apple".isdecimal() == False + assert "4432632479".isdecimal() == True + assert "%#$#$#32A".isdecimal() == False + assert "1.25".isdecimal() == False + assert "-325".isdecimal() == False + assert "12 35".isdecimal() == False + + # Case 2: When variable string is present + s: str + s = "apple" + assert s.isdecimal() == False + s = "238734587" + assert s.isdecimal() == True + s = "%#$#$#32A" + assert s.isdecimal() == False + s = "1.35" + assert s.isdecimal() == False + s = "-42556" + assert s.isdecimal() == False + s = "12 34" + assert s.isdecimal() == False + + +def is_ascii(): + # Case 1: When constant string is present + assert "".isascii() == True + assert " ".isascii() == True + assert "Hello, World123!".isascii() == True + assert "Hëllö, Wörld!".isascii() == False + assert "This is a test string with some non-ASCII characters: 🚀".isascii() == False + assert "\t\n\r".isascii() == True + assert "12 35".isascii() == True + + # # Case 2: When variable string is present + s: str + s = " " + assert s.isascii() == True + s = "Hello, World!" + assert s.isascii() == True + s = "Hëllö, Wörld!" + assert s.isascii() == False + s = "This is a test string with some non-ASCII characters: 🚀" + assert s.isascii() == False + s = "\t\n\r" + assert s.isascii() == True + s = "123 45 6" + assert s.isascii() == True + + +def is_alpha(): + a: str = "helloworld" + b: str = "hj kl" + c: str = "a12(){}A" + d: str = " " + e: str = "" + res: bool = a.isalpha() + res2: bool = b.isalpha() + res3: bool = c.isalpha() + res4: bool = d.isalpha() + res5: bool = e.isalpha() + assert res == True + assert res2 == False + assert res3 == False + assert res4 == False + assert res5 == False + + assert "helloworld".isalpha() == True + assert "hj kl".isalpha() == False + assert "a12(){}A".isalpha() == False + assert " ".isalpha() == False + assert "".isalpha() == False + + +def is_title(): + a: str = "Hello World" + b: str = "Hj'kl" + c: str = "hELlo wOrlD" + d: str = " Hello" + e: str = " " + res: bool = a.istitle() + res2: bool = b.istitle() + res3: bool = c.istitle() + res4: bool = d.istitle() + res5: bool = e.istitle() + assert res == True + assert res2 == False + assert res3 == False + assert res4 == True + assert res5 == False + + assert "Hello World".istitle() == True + assert "Hj'kl".istitle() == False + assert "hELlo wOrlD".istitle() == False + assert " Hello".istitle() == True + assert " ".istitle() == False + +def is_space(): + s0: str = "" + assert s0.isspace() == False + assert "".isspace() == False + + s1: str = " \t\n\v\f\r" + assert s1.isspace() == True + assert " \t\n\v\f\r".isspace() == True + + s2: str = " \t\n\v\f\rabcd" + assert s2.isspace() == False + assert " \t\n\v\f\rabcd".isspace() == False + + s3: str = "abcd \t\n\v\f\ref" + assert s3.isspace() == False + assert "abcd \t\n\v\f\ref".isspace() == False + + s4: str = " \\t\n\v\f\r" + assert s4.isspace() == False + assert " \\t\n\v\f\r".isspace() == False + + s5: str = " \\t\\n\\v\\f\\r" + assert s5.isspace() == False + assert " \\t\\n\\v\\f\\r".isspace() == False + + s6: str = "Hello, LPython!\n" + assert s6.isspace() == False + assert "Hello, LPython!\n".isspace() == False + + s7: str = "\t\tHello! \n" + assert s7.isspace() == False + assert "\t\tHello! \n".isspace() == False + + s8: str = " \t \n \v \f \r " + assert s8.isspace() == True + assert " \t \n \v \f \r ".isspace() == True + + assert "\n".isspace() == True + assert " ".isspace() == True + assert "\r".isspace() == True + assert "".isspace() == False + + s: str = " " + assert s.isspace() == True + s = "a" + assert s.isspace() == False + s = "" + assert s.isspace() == False + +def is_alnum(): + a: str = "helloworld" + b: str = "hj kl" + c: str = "a12(){}A" + d: str = " " + e: str = "" + f: str = "ab23" + g: str = "ab2%3" + res: bool = a.isalnum() + res2: bool = b.isalnum() + res3: bool = c.isalnum() + res4: bool = d.isalnum() + res5: bool = e.isalnum() + res6: bool = f.isalnum() + res7: bool = g.isalnum() + + assert res == True + assert res2 == False + assert res3 == False + assert res4 == False + assert res5 == False + assert res6 == True + assert res7 == False + + assert "helloworld".isalnum() == True + assert "hj kl".isalnum() == False + assert "a12(){}A".isalnum() == False + assert " ".isalnum() == False + assert "".isalnum() == False + assert "ab23".isalnum() == True + assert "ab2%3".isalnum() == False + +def is_numeric(): + a: str = "123" + b: str = "12 34" + c: str = "-123" + d: str = "12.3" + e: str = " " + f: str = "" + g: str = "ab2%3" + res: bool = a.isnumeric() + res2: bool = b.isnumeric() + res3: bool = c.isnumeric() + res4: bool = d.isnumeric() + res5: bool = e.isnumeric() + res6: bool = f.isnumeric() + res7: bool = g.isnumeric() + + assert res == True + assert res2 == False + assert res3 == False + assert res4 == False + assert res5 == False + assert res6 == False + assert res7 == False + + assert "123".isnumeric() == True + assert "12 34".isnumeric() == False + assert "-123".isnumeric() == False + assert "12.3".isnumeric() == False + assert " ".isnumeric() == False + assert "".isnumeric() == False + assert "ab2%3".isnumeric() == False + +def center(): + s: str = "test" + assert s.center(8,'*') == "**test**" + assert s.center(11) == " test " + assert s.center(2) == "test" + assert s.center(4) == "test" + assert s.center(9,'/') == "///test//" + +def expandtabs(): + s: str = '01\t012\t0123\t01234' + assert s.expandtabs() == "01 012 0123 01234" + assert s.expandtabs(4) == "01 012 0123 01234" + assert s.expandtabs(-1) == "01012012301234" + s = '\t' + assert s.expandtabs() == " " + s = '' + assert s.expandtabs() == "" + s = '\tThis\ris\na\ttest' + assert s.expandtabs(4) == " This\ris\na test" + s = '\t\t\t' + assert s.expandtabs(2) == " " + s = 'test\ttest' + assert s.expandtabs(0) == "testtest" + assert s.expandtabs(-5) == "testtest" + def check(): capitalize() lower() + upper() strip() swapcase() find() + count() startswith() + endswith() + partition() + is_lower() + is_upper() + is_decimal() + is_ascii() + is_alpha() + is_title() + is_space() + is_alnum() + is_numeric() + center() + expandtabs() + check() diff --git a/integration_tests/test_str_comparison.py b/integration_tests/test_str_comparison.py index 4ac40aaa78..3108c224e0 100644 --- a/integration_tests/test_str_comparison.py +++ b/integration_tests/test_str_comparison.py @@ -5,18 +5,18 @@ def f(): assert s1 <= s2 assert s1 >= s2 s1 = "abcde" - assert s1 >= s2 + assert s1 >= s2 assert s1 > s2 s1 = "abc" - assert s1 < s2 + assert s1 < s2 assert s1 <= s2 s1 = "Abcd" s2 = "abcd" - assert s1 < s2 + assert s1 < s2 s1 = "orange" s2 = "apple" - assert s1 >= s2 - assert s1 > s2 + assert s1 >= s2 + assert s1 > s2 s1 = "albatross" s2 = "albany" assert s1 >= s2 @@ -28,9 +28,11 @@ def f(): assert s1 < s2 assert s1 != s2 s1 = "Zebra" - s2 = "ant" + s2 = "ant" assert s1 <= s2 assert s1 < s2 assert s1 != s2 + print("Ok") + f() diff --git a/integration_tests/test_str_to_int.py b/integration_tests/test_str_to_int.py index 374ca141f0..3c94dea4b9 100644 --- a/integration_tests/test_str_to_int.py +++ b/integration_tests/test_str_to_int.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def f(): i: i32 @@ -20,4 +20,12 @@ def f(): i = i32(int(s)) assert i == -1234 + assert i32(int("01010",10)) == 1010 + assert i32(int("01010",2)) == 10 + assert i32(int("Beef",16)) == 48879 + assert i32(int("0xE",16)) == 14 + assert i32(int("0xE",0)) == 14 + assert i32(int("123",0)) == 123 + assert i32(int("0bE",16)) == 190 + f() diff --git a/integration_tests/test_string_01.py b/integration_tests/test_string_01.py new file mode 100644 index 0000000000..0e0fef30de --- /dev/null +++ b/integration_tests/test_string_01.py @@ -0,0 +1,9 @@ +from string import ascii_lowercase, ascii_letters + +def test_string(): + assert ascii_lowercase == 'abcdefghijklmnopqrstuvwxyz' + assert ascii_letters == 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + + print(ascii_lowercase) + +test_string() \ No newline at end of file diff --git a/integration_tests/test_sys_01.py b/integration_tests/test_sys_01.py new file mode 100644 index 0000000000..e15e0b4503 --- /dev/null +++ b/integration_tests/test_sys_01.py @@ -0,0 +1,2 @@ +import sys +sys.exit(0) diff --git a/integration_tests/test_tuple_01.py b/integration_tests/test_tuple_01.py index fdafb23b4e..726f7d0e18 100644 --- a/integration_tests/test_tuple_01.py +++ b/integration_tests/test_tuple_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def f(): t1: tuple[i32, f64, str, bool] = (1, 2.0, "3", True) diff --git a/integration_tests/test_tuple_02.py b/integration_tests/test_tuple_02.py index b2218288a5..85dc88381f 100644 --- a/integration_tests/test_tuple_02.py +++ b/integration_tests/test_tuple_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, c64 +from lpython import i32, f64, c64 def set_tuple(a: i32, b: f64) -> tuple[i32, f64, str, c64]: t: tuple[i32, f64, str, c64] diff --git a/integration_tests/test_tuple_03.py b/integration_tests/test_tuple_03.py new file mode 100644 index 0000000000..affd983008 --- /dev/null +++ b/integration_tests/test_tuple_03.py @@ -0,0 +1,10 @@ +from lpython import i32, f64 + +def f(): + t1: tuple[i32, f64, str] = (1, 2.0, "3") + + assert t1[-1] == "3" + assert t1[-2] == 2.0 + assert t1[-3] == 1 + +f() \ No newline at end of file diff --git a/integration_tests/test_tuple_04.py b/integration_tests/test_tuple_04.py new file mode 100644 index 0000000000..393dc51ad0 --- /dev/null +++ b/integration_tests/test_tuple_04.py @@ -0,0 +1,11 @@ +from lpython import i32 + +# issue 2041 +ttype : tuple[list[i32], str] = ([-1], 'dimensions') +contents : tuple[list[i32], str] = ([1, 2], '') + +assert ttype[0] == [-1] +assert len(ttype[0]) == 1 +assert contents[0] == [1, 2] +assert len(contents[1]) == 0 +assert ttype[1] == 'dimensions' diff --git a/integration_tests/test_tuple_concat.py b/integration_tests/test_tuple_concat.py new file mode 100644 index 0000000000..8d09d12593 --- /dev/null +++ b/integration_tests/test_tuple_concat.py @@ -0,0 +1,42 @@ +from lpython import i32, f64 + +def test_tuple_concat(): + t1: tuple[i32, i32] + t2: tuple[f64, str, i32] + t3: tuple[f64] + t4: tuple[i32, i32, f64, str, i32, f64] + t5: tuple[i32, f64] + t6: tuple[i32, f64, i32, f64] + t7: tuple[i32, f64, i32, f64, i32, f64] + t8: tuple[i32, f64, i32, f64, i32, f64, i32, f64] + l1: list[tuple[i32, f64]] = [] + start: i32 + i:i32 + t9: tuple[tuple[tuple[i32, i32], tuple[i32, f64]], tuple[f64, str, i32]] + + t1 = (1, 2) + t2 = (3.0, "abc", -10) + t3 = (10.0,) + t4 = t1 + t2 + t3 + assert t4 == (t1[0], t1[1], t2[0], t2[1], t2[2], t3[0]) + assert t4 + t3 == t1 + t2 + t3 + (t3[0],) + + start = 117 + for i in range(start, start + 3): + t5 = (i, f64(i*i)) + l1.append(t5) + if i == start: + t6 = t5 + l1[-1] + elif i == start + 1: + t7 = t6 + l1[-1] + else: + t8 = t7 + l1[-1] + + assert t6 == l1[0] + l1[0] + assert t7 == t6 + l1[1] + assert t8 == t7 + l1[2] + + t9 = ((t1, t5),) + (t2,) + assert t9[0][0] == t1 and t9[0][1] == t5 and t9[1] == t2 + +test_tuple_concat() \ No newline at end of file diff --git a/integration_tests/test_tuple_nested.py b/integration_tests/test_tuple_nested.py new file mode 100644 index 0000000000..e10ea1b091 --- /dev/null +++ b/integration_tests/test_tuple_nested.py @@ -0,0 +1,35 @@ +from lpython import i32, f64 + +def test_tuple_nested(): + t1: tuple[i32, i32] = (-1, -2) + t2: tuple[i32, i32] = (-3, -4) + t3: tuple[tuple[i32, i32], tuple[i32, i32], tuple[i32, i32], tuple[i32, i32]] + t4: tuple[i32, f64, str] + t5: tuple[tuple[i32, f64, str], i32] + t6: tuple[tuple[tuple[i32, f64, str], i32], f64] + t7: tuple[tuple[i32, i32], tuple[list[i32], list[str]]] + l1: list[tuple[i32, f64, tuple[f64, i32]]] = [] + i: i32 + s: str + + t3 = (t1, t2, t1, t2) + assert t3[0] == t1 and t3[1] == t2 + assert t3[2] == t1 and t3[3] == t2 + + t4 = (1, 2.0, 'abc') + t5 = (t4, 3) + assert t5 == ((1, 2.0, 'abc'), 3) + t6 = (t5, 4.0) + assert t6 == ((t4, 3), 4.0) + + for i in range(5): + l1.append((i, f64(i+1), (f64(i+2), i+3))) + for i in range(5): + assert l1[i] == (i, f64(i+1), (f64(i+2), i+3)) + + i = 3 + s = 'a' + t7 = (t1, ([i, i+1, i+2], [s, s * 2, s * 3])) + assert t7 == ((-1, -2), ([3, 4, 5], ['a', 'aa', 'aaa'])) + +test_tuple_nested() \ No newline at end of file diff --git a/integration_tests/test_types_01.py b/integration_tests/test_types_01.py index 1894ebe961..ee4c1e9169 100644 --- a/integration_tests/test_types_01.py +++ b/integration_tests/test_types_01.py @@ -1,4 +1,4 @@ -from ltypes import i8, i16, i32, i64 +from lpython import i8, i16, i32, i64 def test_i8(): i: i8 diff --git a/integration_tests/test_types_02.py b/integration_tests/test_types_02.py new file mode 100644 index 0000000000..68d338dc94 --- /dev/null +++ b/integration_tests/test_types_02.py @@ -0,0 +1,10 @@ +from lpython import i32, f64 + +def main0(): + a: f64 + a = 3.25 + b: i32 = i32(a) * 4 + print(b) + assert b == 12 + +main0() diff --git a/integration_tests/test_unary_minus.py b/integration_tests/test_unary_minus.py deleted file mode 100644 index 02de00715f..0000000000 --- a/integration_tests/test_unary_minus.py +++ /dev/null @@ -1,15 +0,0 @@ -from ltypes import i32, f64 - -def f(): - eps: f64 - eps = 1e-12 - - i: i32 - i = -67 - assert -i == 67 - - f: f64 - f = -67.6457 - assert abs(-f - 67.6457) < eps - -f() diff --git a/integration_tests/test_unary_op_01.py b/integration_tests/test_unary_op_01.py new file mode 100644 index 0000000000..08182832f1 --- /dev/null +++ b/integration_tests/test_unary_op_01.py @@ -0,0 +1,15 @@ +from lpython import i32, f64 + +def f(): + eps: f64 + eps = 1e-12 + + i: i32 + i = -67 + assert -i == 67 + + f: f64 + f = -67.6457 + assert abs(-f - 67.6457) < eps + +f() diff --git a/integration_tests/test_unary_op_02.py b/integration_tests/test_unary_op_02.py new file mode 100644 index 0000000000..396b8e07cc --- /dev/null +++ b/integration_tests/test_unary_op_02.py @@ -0,0 +1,26 @@ +from lpython import i32, f64, c32 + +def f(): + eps: f64 + eps = 1e-12 + + i: i32 + i = -67 + assert +i == -67 + + f: f64 + f = -67.6457 + assert abs(+f + 67.6457) < eps + + c: c32 + c = c32(4) - c32(5j) + c = +c + assert abs(f64(c.real) - 4.000000) < eps + assert abs(f64(c.imag) - (-5.000000)) < eps + + assert +True == 1 + b: bool + b = False + assert -b == 0 + +f() diff --git a/integration_tests/test_unary_op_03.py b/integration_tests/test_unary_op_03.py new file mode 100644 index 0000000000..48ba56fe5b --- /dev/null +++ b/integration_tests/test_unary_op_03.py @@ -0,0 +1,13 @@ +from lpython import i32 + +def f(): + i: i32 + i = 5 + res: i32 + res = ~i + assert res == -6 + + i = -235346 + assert ~i == 235345 + +f() diff --git a/integration_tests/test_unary_op_04.py b/integration_tests/test_unary_op_04.py new file mode 100644 index 0000000000..a320617ba7 --- /dev/null +++ b/integration_tests/test_unary_op_04.py @@ -0,0 +1,19 @@ +from lpython import u16, bitnot_u16 + +def foo(grp: u16) -> u16: + i: u16 = bitnot_u16(grp) + return i + + +def foo2() -> u16: + i: u16 = bitnot_u16(u16(0xffff)) + return i + +def foo3() -> u16: + i: u16 = bitnot_u16(u16(0xffff)) + return bitnot_u16(i) + +assert foo(u16(0)) == u16(0xffff) +assert foo(u16(0xffff)) == u16(0) +assert foo2() == u16(0) +assert foo3() == u16(0xffff) diff --git a/integration_tests/test_unary_op_05.py b/integration_tests/test_unary_op_05.py new file mode 100644 index 0000000000..c480606591 --- /dev/null +++ b/integration_tests/test_unary_op_05.py @@ -0,0 +1,30 @@ +from lpython import u8, u16, u32, u64 + +def f(): + + h: u8 + h = u8(67) + print(+h) + assert +h == u8(67) + + i: u16 + i = u16(67) + print(+i) + assert +i == u16(67) + + j: u32 + j = u32(25) + print(+j) + assert +j == u32(25) + + k: u64 + k = u64(100000000000123) + print(+k) + assert +k == u64(100000000000123) + + assert -u8(0) == u8(0) + assert -u16(0) == u16(0) + assert -u32(0) == u32(0) + assert -u64(0) == u64(0) + +f() diff --git a/integration_tests/test_unary_op_06.py b/integration_tests/test_unary_op_06.py new file mode 100644 index 0000000000..212d7b1609 --- /dev/null +++ b/integration_tests/test_unary_op_06.py @@ -0,0 +1,35 @@ +from lpython import i32, i64, u16, u64, f32, f64 + +def f(): + + i: i32 + j: i64 + i = -67 + j = i64(0) + + print(i, j) + print(not i, not j) + assert (not i) == False + assert (not j) == True + + k: u16 + l: u64 + k = u16(0) + l = u64(55) + + print(k, l) + print(not k, not l) + assert (not k) == True + assert (not l) == False + + m: f32 + n: f64 + m = f32(0.0) + n = -3.14 + + print(m, n) + print(not m, not n) + assert (not m) == True + assert (not n) == False + +f() diff --git a/integration_tests/test_unary_plus.py b/integration_tests/test_unary_plus.py deleted file mode 100644 index 7067c03639..0000000000 --- a/integration_tests/test_unary_plus.py +++ /dev/null @@ -1,26 +0,0 @@ -from ltypes import i32, f64, c32 - -def f(): - eps: f64 - eps = 1e-12 - - i: i32 - i = -67 - assert +i == -67 - - f: f64 - f = -67.6457 - assert abs(+f + 67.6457) < eps - - c: c32 - c = c32(4) - c32(5j) - c = +c - assert abs(f64(c.real) - 4.000000) < eps - assert abs(f64(c.imag) - (-5.000000)) < eps - - assert +True == 1 - b: bool - b = False - assert -b == 0 - -f() diff --git a/integration_tests/test_unsigned_01.py b/integration_tests/test_unsigned_01.py new file mode 100644 index 0000000000..44068cceb3 --- /dev/null +++ b/integration_tests/test_unsigned_01.py @@ -0,0 +1,37 @@ +from lpython import u8, u16, u32, u64 + +def f(): + + h: u8 + h = u8(5) + print(h << u8(4), h << u8(2), h >> u8(4), h >> u8(7)) + assert h << u8(4) == u8(80) + assert h << u8(2) == u8(20) + assert h >> u8(4) == u8(0) + assert h >> u8(7) == u8(0) + + i: u16 + i = u16(67) + print(i << u16(4), i << u16(7), i >> u16(4), i >> u16(7)) + assert i << u16(4) == u16(1072) + assert i << u16(7) == u16(8576) + assert i >> u16(4) == u16(4) + assert i >> u16(7) == u16(0) + + j: u32 + j = u32(25) + print(j << u32(4), j << u32(7), j >> u32(4), j >> u32(7)) + assert j << u32(4) == u32(400) + assert j << u32(7) == u32(3200) + assert j >> u32(4) == u32(1) + assert j >> u32(7) == u32(0) + + k: u64 + k = u64(100000000000123) + print(k << u64(4), k << u64(7), k >> u64(4), k >> u64(7)) + assert k << u64(4) == u64(1600000000001968) + assert k << u64(7) == u64(12800000000015744) + assert k >> u64(4) == u64(6250000000007) + assert k >> u64(7) == u64(781250000000) + +f() diff --git a/integration_tests/test_unsigned_02.py b/integration_tests/test_unsigned_02.py new file mode 100644 index 0000000000..ad7f938249 --- /dev/null +++ b/integration_tests/test_unsigned_02.py @@ -0,0 +1,15 @@ +from lpython import u16, i32, u8, u32, u64 + +# test issue 2170 + +u_1 : u16 = u16(32768) +u_2 : u8 = u8(24) +u_3 : u32 = u32(32768) +u_4 : u64 = u64(32768) + +assert u_1 == u16(32768) +assert u_2 == u8(24) +assert u_3 == u32(32768) +assert u_4 == u64(32768) + +print(u_1, u_2, u_3, u_4) diff --git a/integration_tests/test_unsigned_03.py b/integration_tests/test_unsigned_03.py new file mode 100644 index 0000000000..2bc0eaeac2 --- /dev/null +++ b/integration_tests/test_unsigned_03.py @@ -0,0 +1,19 @@ +from lpython import u16, i32, u8, u16, u64, i64, u32, i8 + +# test issue 2174 + +def f(): + u: u16 = u16(32768) + assert i32(u) == 32768 + u1: u8 = u8(23) + assert i8(u1) == i8(23) + assert u16(u1) == u16(23) + assert u32(u1) == u32(23) + assert u64(u1) == u64(23) + print(i8(u1), u16(u1), u32(u1), u64(u1)) + assert i64(u1) == i64(23) + assert i64(u) == i64(32768) + assert i32(u1) == 23 + print(i64(u), i32(u)) + +f() diff --git a/integration_tests/union_01.py b/integration_tests/union_01.py index 05cff1bf78..7fda2326df 100644 --- a/integration_tests/union_01.py +++ b/integration_tests/union_01.py @@ -1,4 +1,4 @@ -from ltypes import Union, i32, i64, f64, f32, ccall, union +from lpython import Union, i32, i64, f64, f32, ccall, union @ccall @union diff --git a/integration_tests/union_02.py b/integration_tests/union_02.py index dd693ef041..67cb4a3254 100644 --- a/integration_tests/union_02.py +++ b/integration_tests/union_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, i64, dataclass, ccall, union, Union +from lpython import i32, f64, i64, dataclass, ccall, union, Union @dataclass class A: @@ -19,9 +19,9 @@ class C: @ccall @union class D(Union): - a: A - b: B - c: C + a: A = A(0, 3.0) + b: B = B(i64(0), 2.0) + c: C = C(i64(0), 0.0, 1.0) def test_struct_union(): d: D = D() diff --git a/integration_tests/union_03.py b/integration_tests/union_03.py index 5033085158..4c8c538ac4 100644 --- a/integration_tests/union_03.py +++ b/integration_tests/union_03.py @@ -1,4 +1,4 @@ -from ltypes import Union, i32, i64, f64, f32, union +from lpython import Union, i32, i64, f64, f32, union # without ccall but same as union_01.py @union diff --git a/integration_tests/union_04.py b/integration_tests/union_04.py new file mode 100644 index 0000000000..58a604ecc1 --- /dev/null +++ b/integration_tests/union_04.py @@ -0,0 +1,24 @@ +from union_01 import u_type +from lpython import f32, f64, i64 + +# Test taken from union_01.py but checks importing union + +def test_union_04(): + unionobj: u_type = u_type() + unionobj.integer32 = 1 + print(unionobj.integer32) + assert unionobj.integer32 == 1 + + unionobj.real32 = f32(2.0) + print(unionobj.real32) + assert abs(f64(unionobj.real32) - 2.0) <= 1e-6 + + unionobj.real64 = 3.5 + print(unionobj.real64) + assert abs(unionobj.real64 - 3.5) <= 1e-12 + + unionobj.integer64 = i64(4) + print(unionobj.integer64) + assert unionobj.integer64 == i64(4) + +test_union_04() diff --git a/integration_tests/variable_decl_01.py b/integration_tests/variable_decl_01.py index 9672366969..669470411c 100644 --- a/integration_tests/variable_decl_01.py +++ b/integration_tests/variable_decl_01.py @@ -1,8 +1,8 @@ -from ltypes import i32, i64 +from lpython import i32, i64, Const from numpy import empty, int64 def f(n: i32, m: i32): - l: i32 = 2 + l: Const[i32] = 2 a: i64[n, m, l] = empty((n, m, l), dtype=int64) i: i32; j: i32; k: i32; for i in range(n): diff --git a/integration_tests/variable_decl_02.py b/integration_tests/variable_decl_02.py index 08d1486552..9ee2a67034 100644 --- a/integration_tests/variable_decl_02.py +++ b/integration_tests/variable_decl_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, i64 +from lpython import i32, i64 def f(): d: i32 = 0 diff --git a/integration_tests/variable_decl_03.py b/integration_tests/variable_decl_03.py new file mode 100644 index 0000000000..f554b9fc5d --- /dev/null +++ b/integration_tests/variable_decl_03.py @@ -0,0 +1,11 @@ +from lpython import f64 + +def f() -> f64: + return abs(-5.5) + +def main(): + t1: f64 = f() * 1e6 + print(t1) + assert abs(t1 - 5.5 * 1e6) <= 1e-6 + +main() diff --git a/integration_tests/vec_01.py b/integration_tests/vec_01.py index 4bbcb87522..8d93b8b9c2 100644 --- a/integration_tests/vec_01.py +++ b/integration_tests/vec_01.py @@ -1,9 +1,9 @@ -from ltypes import f64 -from numpy import empty +from lpython import f64, i32 +from numpy import empty, float64 def loop_vec(): - a: f64[9216] = empty(9216) - b: f64[9216] = empty(9216) + a: f64[9216] = empty(9216, dtype=float64) + b: f64[9216] = empty(9216, dtype=float64) i: i32 for i in range(9216): diff --git a/libasr b/libasr new file mode 160000 index 0000000000..f2a04fc2ae --- /dev/null +++ b/libasr @@ -0,0 +1 @@ +Subproject commit f2a04fc2ae4dd9ccb940c0fee3f694791fec7005 diff --git a/run_tests.py b/run_tests.py index 6363b1c0d4..d45335ec3a 100755 --- a/run_tests.py +++ b/run_tests.py @@ -4,13 +4,13 @@ import os ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__))) -sys.path.append(os.path.join(ROOT_DIR, "src", "libasr")) +sys.path.append(os.path.join(ROOT_DIR, "libasr", "src", "libasr")) from compiler_tester.tester import color, fg, log, run_test, style, tester_main def single_test(test, verbose, no_llvm, skip_run_with_dbg, update_reference, - no_color, specific_backends=None, excluded_backends=None): + verify_hash, no_color, specific_backends=None, excluded_backends=None): filename = test["filename"] def is_included(backend): return test.get(backend, False) \ @@ -21,19 +21,25 @@ def is_included(backend): ast = is_included("ast") ast_new = is_included("ast_new") asr = is_included("asr") + asr_json = is_included("asr_json") llvm = is_included("llvm") llvm_dbg = is_included("llvm_dbg") cpp = is_included("cpp") c = is_included("c") + python = is_included("python") + is_cumulative = is_included("cumulative") wat = is_included("wat") run = is_included("run") run_with_dbg = is_included("run_with_dbg") + disable_main = is_included("disable_main") + fast = is_included("fast") pass_ = test.get("pass", None) optimization_passes = ["flip_sign", "div_to_mul", "fma", "sign_from_value", "inline_function_calls", "loop_unroll", - "dead_code_removal", "loop_vectorise", "print_list"] + "dead_code_removal", "loop_vectorise", "print_list_tuple", + "class_constructor"] - if pass_ and (pass_ not in ["do_loops", "global_stmts"] and + if pass_ and (pass_ not in ["do_loops", "global_stmts", "while_else"] and pass_ not in optimization_passes): raise Exception(f"Unknown pass: {pass_}") if no_color: @@ -50,7 +56,7 @@ def is_included(backend): "lpython --no-color --show-tokens {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if ast: run_test( @@ -59,7 +65,7 @@ def is_included(backend): "lpython --show-ast --no-color {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if ast_new: run_test( @@ -68,7 +74,7 @@ def is_included(backend): "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if asr: run_test( @@ -77,13 +83,27 @@ def is_included(backend): "lpython --show-asr --no-color {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) + + if asr_json: + run_test( + filename, + "asr_json", + "lpython --show-asr --json --no-color {infile} -o {outfile}", + filename, + update_reference, + extra_args=extra_args) if pass_ is not None: - cmd = "lpython --pass=" + pass_ + \ + cmd = "lpython " + if is_cumulative: + cmd += "--cumulative " + if fast: + cmd += "--fast " + cmd += "--pass=" + pass_ + \ " --show-asr --no-color {infile} -o {outfile}" run_test(filename, "pass_{}".format(pass_), cmd, - filename, update_reference, extra_args) + filename, update_reference, extra_args=extra_args) if no_llvm: log.info(f"{filename} * llvm SKIPPED as requested") @@ -95,7 +115,7 @@ def is_included(backend): "lpython --no-color --show-llvm {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if llvm_dbg: run_test( filename, @@ -104,22 +124,31 @@ def is_included(backend): "{infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if cpp: run_test(filename, "cpp", "lpython --no-color --show-cpp {infile}", - filename, update_reference, extra_args) + filename, update_reference, extra_args=extra_args) if c: - run_test(filename, "c", "lpython --no-color --show-c {infile}", - filename, update_reference, extra_args) + if disable_main: + run_test(filename, "c", "lpython --no-color --disable-main --show-c {infile}", + filename, update_reference, extra_args=extra_args) + else: + run_test(filename, "c", "lpython --no-color --show-c {infile}", + filename, update_reference, extra_args=extra_args) + + if python: + run_test(filename, "python", "lpython --no-color --show-python {infile}", + filename, update_reference, extra_args=extra_args) + if wat: run_test(filename, "wat", "lpython --no-color --show-wat {infile}", - filename, update_reference, extra_args) + filename, update_reference, extra_args=extra_args) if run: run_test(filename, "runtime", "lpython {infile}", - filename, update_reference, extra_args) + filename, update_reference, extra_args=extra_args) if run_with_dbg: if skip_run_with_dbg: @@ -128,7 +157,7 @@ def is_included(backend): run_test( filename, "run_dbg", "lpython {infile} -g --debug-with-line-column --no-color", - filename, update_reference, extra_args) + filename, update_reference, extra_args=extra_args) if __name__ == "__main__": tester_main("LPython", single_test) diff --git a/share/jupyter/kernels/lpython/kernel.json.in b/share/jupyter/kernels/lpython/kernel.json.in new file mode 100644 index 0000000000..e1af020ba4 --- /dev/null +++ b/share/jupyter/kernels/lpython/kernel.json.in @@ -0,0 +1,10 @@ +{ + "display_name": "LPython", + "argv": [ + "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/lpython", + "kernel", + "-f", + "{connection_file}" + ], + "language": "python" +} diff --git a/share/lpython/lfortran-completion.bash b/share/lpython/lfortran-completion.bash index ca63ca03bd..69bb236096 100644 --- a/share/lpython/lfortran-completion.bash +++ b/share/lpython/lfortran-completion.bash @@ -1,6 +1,6 @@ #/usr/bin/env bash complete \ - -W "-h --help -S -c -o -v -E -I --version --cpp --fixed-form --show-prescan --show-tokens --show-ast --show-asr --with-intrinsic-modules --show-ast-f90 --no-color --indent --pass --show-llvm --show-cpp --show-stacktrace --time-report --static --backend --openmp fmt kernel mod pywrap" \ + -W "-h --help -S -c -o -v -E -I --version --cpp --fixed-form --show-prescan --show-tokens --show-ast --show-asr --with-intrinsic-modules --show-ast-f90 --no-color --pass --show-llvm --show-cpp --show-stacktrace --time-report --static --backend --openmp fmt kernel mod pywrap" \ -df \ lfortran diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 061b942762..ebba706be4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -add_subdirectory(libasr) +add_subdirectory(${CMAKE_SOURCE_DIR}/libasr/src/libasr ${CMAKE_BINARY_DIR}/libasr) add_subdirectory(tests) add_subdirectory(lpython) add_subdirectory(bin) diff --git a/src/bin/CLI11.hpp b/src/bin/CLI11.hpp index ce1d06e3f2..f3647aceff 100644 --- a/src/bin/CLI11.hpp +++ b/src/bin/CLI11.hpp @@ -4191,7 +4191,7 @@ class Option : public OptionBase