diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..e27c05fcfa --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +**/*.py -text diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4110a71ee2..362159b5a7 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -4,10 +4,13 @@ on: push: branches: - main + tags: + - 'v*' pull_request: branches: - main - +env: + MACOSX_DEPLOYMENT_TARGET: 14.0 jobs: Build: @@ -19,12 +22,12 @@ jobs: os: ["ubuntu-latest", "macos-latest", "windows-2019"] python-version: ["3.10"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - name: Cache conda - uses: actions/cache@v2 + uses: actions/cache@v3 env: CACHE_NUMBER: 0 with: @@ -32,47 +35,49 @@ 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 - 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 nodejs=18 - 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 echo "MACOS=0" >> $GITHUB_ENV + echo "ENABLE_RUNTIME_STACKTRACE=yes" >> $GITHUB_ENV - 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 echo "MACOS=1" >> $GITHUB_ENV + 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 @@ -81,17 +86,18 @@ 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" 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 @@ -100,9 +106,9 @@ 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 @@ -111,16 +117,16 @@ jobs: 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: fetch-depth: 0 - - uses: mamba-org/provision-with-micromamba@main + - uses: mamba-org/setup-micromamba@v1 with: environment-file: ci/environment.yml - extra-specs: | + create-args: >- python=3.10 bison=3.4 @@ -129,6 +135,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: | @@ -138,13 +151,12 @@ jobs: git clone https://github.com/emscripten-core/emsdk.git cd emsdk - # Download and install the latest SDK tools. - ./emsdk install latest - - # Make the "latest" SDK "active" for the current user. (writes .emscripten file) - ./emsdk activate latest + ./emsdk install 3.1.35 + ./emsdk activate 3.1.35 + ./emsdk install node-14.18.2-64bit + ./emsdk activate node-14.18.2-64bit - - name: Show Emscripten Info + - name: Show Emscripten and Node Info shell: bash -l {0} run: | set -ex @@ -152,13 +164,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 @@ -166,4 +179,439 @@ jobs: run: | set -ex source $HOME/ext/emsdk/emsdk_env.sh # Activate Emscripten - node src/lpython/tests/test_lpython.js + which node + node -v + node --experimental-wasm-bigint src/lpython/tests/test_lpython.js + + test_pip_pkgs: + name: Test PIP Installable Packages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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: + fetch-depth: 0 + + - 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 +# 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 +# Generate the intrinsic_function_registry_util.h (C++) +python 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 diff --git a/build1.bat b/build1.bat new file mode 100644 index 0000000000..93f92be9c2 --- /dev/null +++ b/build1.bat @@ -0,0 +1,10 @@ +cmake ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DWITH_LLVM=yes ^ + -DLPYTHON_BUILD_ALL=yes ^ + -DWITH_STACKTRACE=no ^ + -DCMAKE_PREFIX_PATH="%CONDA_PREFIX%" ^ + -DCMAKE_INSTALL_PREFIX=%cd%/inst ^ + . -G "Ninja" + +cmake --build . --config Release -j8 --target install diff --git a/build1.sh b/build1.sh index 376783d79b..8bf7476431 100755 --- a/build1.sh +++ b/build1.sh @@ -8,6 +8,7 @@ cmake \ -DWITH_LLVM=yes \ -DLPYTHON_BUILD_ALL=yes \ -DWITH_STACKTRACE=yes \ + -DWITH_RUNTIME_STACKTRACE=yes \ -DWITH_LSP=no \ -DWITH_LFORTRAN_BINARY_MODFILES=no \ -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH_LPYTHON;$CONDA_PREFIX" \ diff --git a/build1_win.sh b/build1_win.sh deleted file mode 100644 index 9eeb3fe585..0000000000 --- a/build1_win.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -bash ci/version.sh -# 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 -# Generate a Fortran ASR from ASR.asdl (C++) -python src/libasr/asdl_cpp.py src/libasr/ASR.asdl src/libasr/asr.h 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 b95646b1c2..449d89543f 100755 --- a/ci/build.xsh +++ b/ci/build.xsh @@ -34,6 +34,8 @@ python src/libasr/asdl_cpp.py grammar/Python.asdl src/lpython/python_ast.h 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 the intrinsic_function_registry_util.h (C++) +python 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 @@ -51,7 +53,7 @@ cd test-bld # compiled in Release mode and we get link failures if we mix and match build # modes: BUILD_TYPE = "Release" -cmake -G $LFORTRAN_CMAKE_GENERATOR -DCMAKE_VERBOSE_MAKEFILE=ON -DWITH_LLVM=yes -DWITH_LSP=yes -DWITH_XEUS=yes -DCMAKE_PREFIX_PATH=$CONDA_PREFIX -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DWITH_LFORTRAN_BINARY_MODFILES=no -DCMAKE_BUILD_TYPE=@(BUILD_TYPE) .. +cmake -G $LFORTRAN_CMAKE_GENERATOR -DCMAKE_VERBOSE_MAKEFILE=ON -DWITH_LLVM=yes -DWITH_LSP=yes -DWITH_XEUS=yes -DCMAKE_PREFIX_PATH=$CONDA_PREFIX -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DWITH_LFORTRAN_BINARY_MODFILES=no -DCMAKE_BUILD_TYPE=@(BUILD_TYPE) -DWITH_RUNTIME_STACKTRACE=$ENABLE_RUNTIME_STACKTRACE .. cmake --build . --target install -j16 ./src/lpython/tests/test_lpython #./src/bin/lpython < ../src/bin/example_input.txt 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/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 7648396076..6e2c45ac51 100644 --- a/ci/test.xsh +++ b/ci/test.xsh @@ -15,7 +15,19 @@ 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 -if $WIN != "1": +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 - ./run_tests.sh -j16 + + 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=$( 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 505e406a25..dff2027ff7 100644 --- a/doc/src/installation.md +++ b/doc/src/installation.md @@ -1,146 +1,209 @@ # 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 + ``` + + You may also use GitHub Desktop to do the same. + +## Building LPython +- ### Linux and macOS + - Create a Conda environment: -## Binaries + ```bash + conda env create -f environment_unix.yml + conda activate lp + ``` -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`. + - Generate the prerequisite files and build in Debug Mode: -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`. + ```bash + # if you are developing on top of a forked repository; please run following command first + # ./generate_default_tag.sh -## Build From a Source Tarball + ./build0.sh + ./build1.sh + ``` -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. +- ### Windows + - Create a Conda environment using the pre-existing file: -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 + conda env create -f environment_win.yml + conda activate lp + ``` -## Build From Git + - Generate the prerequisite files and build in Release Mode: -We assume you have C++ compilers installed, as well as `git` and `wget`. -In Ubuntu, you can also install `binutils-dev` for stacktraces. + ```bash + call build0.bat + call build1.bat + ``` +- ### Windows with WSL -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 -``` + - Activate the Conda environment: + ```bash + conda activate lp + ``` -Run tests: -```bash -ctest -./run_tests.py -``` -Run an interactive prompt: -```bash -./src/bin/lfortran -``` + - 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 + ``` -## Build on Windows with Visual Studio +## 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). +- ### Linux and macOS -First, clone the repo to a local folder. + - Run tests: -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 -``` + ```bash + ctest + ./run_tests.py + ``` + + - Update test references: + ``` + ./run_tests.py -u + ``` + + - 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 -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 Setttings 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 + ```bash + python run_tests.py --skip-run-with-dbg + ``` -Then you can generate the CMake-Cache and build the project. + - Update reference tests + + ```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 +212,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 +Click `New->LPython`. To launch a terminal jupyter LPython console: ``` -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" +jupyter console --kernel=lpython ``` -### Development +## 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). -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. +We welcome all changes, big or small. We will help you make a PR if you are new to git. -The build steps are the same as with the `ci`: -```bash -./build0.sh -./build1.sh -``` - -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" -``` - -## 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, - -- [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`). - -## 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 b0449002aa..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,13 +56,13 @@ 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. -history of your commits will show up on your editor, you have options to do with commits and they are written bellow commits history. +history of your commits will show up on your editor, you have options to do with commits and they are written below commits history. ```bash pick 132b89e0c Added add.py pick 75556f15c Added add2.py @@ -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` becasue we squashed the commit after it, and by default the mwssage 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 becasue 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.yml b/environment_unix.yml similarity index 86% rename from environment.yml rename to environment_unix.yml index 68e90f1401..af7dffcff0 100644 --- a/environment.yml +++ b/environment_unix.yml @@ -2,15 +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 + - 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 new file mode 100644 index 0000000000..60774b822c --- /dev/null +++ b/environment_win.yml @@ -0,0 +1,20 @@ +name: lp +channels: + - conda-forge +dependencies: + - git + - pip + - make + - re2c + - toml + - zlib + - cmake + - ninja + - numpy + - xonsh + - flake8 + - setuptools + - python=3.10.2 + - m2-bison=3.0.4 + - 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/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index fa9ff6bdda..5ad8a0074d 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,201 +69,796 @@ 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) - set(multiValueArgs LABELS EXTRAFILES) - cmake_parse_arguments(RUN "${options}" "${oneValueArgs}" - "${multiValueArgs}" ${ARGN} ) - set(name ${RUN_NAME}) 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") 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 + 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 ${RUN_EXTRAFILES}) + 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}) - set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + 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() + 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 --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py > ${name}.c - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + 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 ${RUN_EXTRAFILES}) + 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}) - set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + 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}/${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 (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} ${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 (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + 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} ${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 (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + 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} ${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 (labels) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + elseif(KIND STREQUAL "wasm") + # wasm test + 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(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/ltypes;LPYTHON_PY_MOD_NAME=${PY_MOD};LPYTHON_PY_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}") + 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() if (${RUN_FAIL}) - set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) 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_expr_01 LABELS cpython llvm) -RUN(NAME array_expr_02 LABELS cpython llvm) -RUN(NAME bindc_01 LABELS llvm c) -RUN(NAME bindc_02 LABELS llvm c) -RUN(NAME bindc_04 LABELS llvm) -RUN(NAME exit_01 LABELS cpython llvm c) -RUN(NAME exit_02 FAIL LABELS cpython llvm c) -RUN(NAME exit_01b LABELS cpython llvm c) -RUN(NAME exit_02b FAIL LABELS cpython llvm c) -RUN(NAME exit_02c FAIL LABELS cpython llvm c) - -# Test all three backends -RUN(NAME print_01 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 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) +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) +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) +RUN(NAME bindc_09b LABELS cpython llvm llvm_jit c) +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 c NOFAST) +RUN(NAME exit_02 FAIL LABELS cpython llvm llvm_jit c NOFAST) +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 llvm_jit c wasm) # wasm not yet supports sep and end keywords +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 llvm_jit c) +RUN(NAME print_06 LABELS cpython llvm llvm_jit 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 c NOFAST) +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 c NOFAST) +RUN(NAME test_intrinsic_function_mixed_print LABELS cpython llvm llvm_jit NOFAST) # CPython and LLVM -RUN(NAME expr_01 LABELS cpython llvm c) -RUN(NAME expr_02 LABELS cpython llvm c) -RUN(NAME expr_03 LABELS cpython llvm c) -RUN(NAME expr_04 LABELS cpython llvm c) -RUN(NAME expr_05 LABELS cpython llvm c) -RUN(NAME expr_06 LABELS cpython llvm c) -RUN(NAME expr_07 LABELS cpython llvm) -RUN(NAME expr_08 LABELS llvm c) -RUN(NAME expr_09 LABELS cpython llvm) -RUN(NAME expr_10 LABELS cpython llvm) -RUN(NAME expr_11 LABELS cpython llvm c) -RUN(NAME expr_12 LABELS llvm c) -RUN(NAME loop_01 LABELS cpython llvm c) -RUN(NAME test_types_01 LABELS cpython llvm) -RUN(NAME test_str_01 LABELS cpython llvm) -RUN(NAME test_str_02 LABELS cpython llvm) -RUN(NAME test_str_03 LABELS cpython llvm c) -RUN(NAME test_list_01 LABELS cpython llvm) -RUN(NAME test_list_02 LABELS cpython llvm) -RUN(NAME test_list_03 LABELS cpython llvm) -RUN(NAME test_list_04 LABELS cpython llvm) -RUN(NAME test_list_05 LABELS cpython llvm) -RUN(NAME test_list_06 LABELS cpython llvm) -RUN(NAME test_list_07 LABELS cpython llvm) -RUN(NAME test_list_08 LABELS cpython llvm) -RUN(NAME test_tuple_01 LABELS cpython llvm) -RUN(NAME test_tuple_02 LABELS cpython llvm) -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 modules_01 LABELS cpython llvm) -RUN(NAME modules_02 LABELS cpython llvm) -RUN(NAME test_math LABELS cpython llvm) -RUN(NAME test_numpy_01 LABELS cpython llvm) -RUN(NAME test_numpy_02 LABELS cpython llvm) -RUN(NAME test_numpy_03 LABELS cpython llvm) -RUN(NAME test_numpy_04 LABELS cpython llvm) -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 test_random LABELS cpython llvm) -RUN(NAME test_os LABELS cpython llvm) -RUN(NAME test_builtin LABELS cpython llvm) -RUN(NAME test_builtin_abs LABELS cpython llvm) -RUN(NAME test_builtin_bool LABELS cpython llvm) -RUN(NAME test_builtin_pow LABELS cpython llvm) -RUN(NAME test_builtin_int LABELS cpython llvm) -RUN(NAME test_builtin_len LABELS cpython llvm) -RUN(NAME test_builtin_str LABELS cpython llvm) -RUN(NAME test_builtin_oct LABELS cpython llvm) -RUN(NAME test_builtin_hex LABELS cpython llvm) -RUN(NAME test_builtin_bin LABELS cpython llvm) -RUN(NAME test_builtin_float LABELS cpython llvm) -RUN(NAME test_builtin_str_02 LABELS cpython llvm) -RUN(NAME test_builtin_round LABELS cpython llvm) -RUN(NAME test_builtin_divmod LABELS cpython llvm) -RUN(NAME test_math1 LABELS cpython llvm) -RUN(NAME test_math_02 LABELS cpython llvm) -RUN(NAME test_c_interop_01 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 llvm_jit c) +RUN(NAME expr_01 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME expr_02 LABELS cpython llvm llvm_jit c wasm wasm_x64) +RUN(NAME expr_03 LABELS cpython llvm llvm_jit c wasm 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) +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) +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 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 c NOFAST) +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 c NOFAST) +RUN(NAME print_02 LABELS cpython llvm llvm_jit c) +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 c) +RUN(NAME test_str_03 LABELS cpython llvm llvm_jit c) +RUN(NAME test_str_04 LABELS cpython llvm llvm_jit c wasm) +RUN(NAME test_str_05 LABELS cpython llvm llvm_jit c) +RUN(NAME test_str_06 LABELS cpython llvm llvm_jit c) +RUN(NAME test_string_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_list_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_list_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_list_03 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_list_04 LABELS cpython llvm llvm_jit c NOFAST) +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 c NOFAST) +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) +RUN(NAME test_list_index LABELS cpython llvm llvm_jit) +RUN(NAME test_list_index2 LABELS cpython llvm llvm_jit) +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) +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) +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) +RUN(NAME test_const_list LABELS cpython llvm llvm_jit) +RUN(NAME test_const_access LABELS cpython llvm llvm_jit) +RUN(NAME test_tuple_01 LABELS cpython llvm llvm_jit c) +RUN(NAME test_tuple_02 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME test_tuple_03 LABELS cpython llvm llvm_jit c) +RUN(NAME test_tuple_04 LABELS cpython llvm llvm_jit c) +RUN(NAME test_tuple_concat LABELS cpython llvm llvm_jit) +RUN(NAME test_tuple_nested LABELS cpython llvm llvm_jit) +RUN(NAME test_const_dict LABELS cpython llvm llvm_jit) +RUN(NAME test_params LABELS cpython llvm llvm_jit NOFAST) +RUN(NAME test_dict_01 LABELS cpython llvm llvm_jit c) +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 c) +RUN(NAME test_dict_11 LABELS cpython llvm llvm_jit c) +RUN(NAME test_dict_12 LABELS cpython llvm llvm_jit c) +RUN(NAME test_dict_13 LABELS cpython llvm llvm_jit c) +RUN(NAME test_dict_bool LABELS cpython llvm llvm_jit) +RUN(NAME test_dict_increment LABELS cpython llvm llvm_jit) +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) +RUN(NAME test_set_add LABELS cpython llvm llvm_jit) +RUN(NAME test_set_remove LABELS cpython llvm llvm_jit) +RUN(NAME test_set_discard 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) +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 c) +RUN(NAME test_import_02 LABELS cpython llvm llvm_jit c) +RUN(NAME test_import_03 LABELS cpython llvm llvm_jit 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_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 c NOFAST) +RUN(NAME elemental_02 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_03 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_04 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_05 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_06 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_07 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_08 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_09 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_10 LABELS cpython llvm llvm_jit c NOFAST) +RUN(NAME elemental_11 LABELS cpython llvm llvm_jit c NOFAST) +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 c NOFAST) +RUN(NAME test_builtin LABELS cpython llvm llvm_jit c) +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 c) +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 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 +RUN(NAME bindc_03 LABELS llvm c EXTRAFILES bindc_03b.c) -RUN(NAME test_generics_01 LABELS cpython llvm) -RUN(NAME test_cmath LABELS cpython llvm) -RUN(NAME test_complex LABELS cpython llvm) -RUN(NAME test_max_min LABELS cpython llvm) -RUN(NAME test_global LABELS cpython llvm) -RUN(NAME test_integer_bitnot LABELS cpython llvm) -RUN(NAME test_ifexp LABELS cpython llvm) -RUN(NAME test_unary_minus LABELS cpython llvm) -RUN(NAME test_unary_plus LABELS cpython llvm) -RUN(NAME test_bool_binop LABELS cpython llvm) -RUN(NAME test_issue_518 LABELS cpython llvm) -RUN(NAME structs_01 LABELS cpython llvm c) -RUN(NAME structs_02 LABELS 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 test_str_to_int LABELS cpython llvm) -RUN(NAME test_platform LABELS cpython llvm) -RUN(NAME test_vars_01 LABELS cpython llvm) -RUN(NAME test_version LABELS cpython llvm) -RUN(NAME vec_01 LABELS cpython llvm) -RUN(NAME test_str_comparison LABELS cpython llvm) -RUN(NAME test_bit_length LABELS cpython llvm) -RUN(NAME str_to_list_cast LABELS cpython llvm) - -RUN(NAME generics_01 LABELS cpython llvm) -RUN(NAME generics_02 LABELS cpython llvm) -RUN(NAME generics_array_01 LABELS llvm) -RUN(NAME generics_list_01 LABELS cpython llvm) -RUN(NAME test_statistics LABELS cpython llvm) -RUN(NAME test_str_attributes LABELS cpython llvm) -RUN(NAME kwargs_01 LABELS cpython llvm) +RUN(NAME bindc_05 LABELS llvm c + EXTRAFILES bindc_05b.c) +RUN(NAME bindc_06 LABELS llvm c + EXTRAFILES bindc_06b.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 c NOFAST) +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 c) +RUN(NAME test_global_decl LABELS cpython llvm llvm_jit 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) +RUN(NAME structs_26 LABELS cpython llvm llvm_jit c) +RUN(NAME structs_27 LABELS cpython llvm llvm_jit c) +RUN(NAME structs_28 LABELS cpython llvm llvm_jit c) +RUN(NAME structs_29 LABELS cpython llvm llvm_jit) +RUN(NAME structs_30 LABELS cpython llvm llvm_jit 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 c_sym llvm_sym llvm_jit EXTRA_ARGS --enable-symengine) +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) +RUN(NAME enum_02 LABELS cpython llvm llvm_jit) +RUN(NAME enum_03 LABELS cpython llvm llvm_jit c) +RUN(NAME enum_04 LABELS cpython llvm llvm_jit c) +RUN(NAME enum_05 LABELS llvm c + EXTRAFILES enum_05b.c) +RUN(NAME enum_06 LABELS cpython llvm llvm_jit c) +RUN(NAME enum_07 IMPORT_PATH .. + LABELS cpython llvm llvm_jit c) +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 c) +RUN(NAME test_vars_01 LABELS cpython llvm llvm_jit) +RUN(NAME test_version LABELS cpython llvm llvm_jit) +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 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 c) +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 c) +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 c NOFAST) +RUN(NAME def_func_01 LABELS cpython llvm llvm_jit c) + +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 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 new file mode 100644 index 0000000000..c492d6b31c --- /dev/null +++ b/integration_tests/array_01.py @@ -0,0 +1,17 @@ +from lpython import i32 +from numpy import empty, int32 + +def main0(): + Nx: i32 = 600; Ny: i32 = 450 + arr: i32[450, 600] = empty([450, 600], dtype=int32) + i: i32 + j: i32 + for i in range(Ny): + for j in range(Nx): + arr[i, j] = i * j + + for i in range(Ny): + for j in range(Nx): + print(i, j, int(arr[i, j])) + +main0() diff --git a/integration_tests/array_01_decl.py b/integration_tests/array_01_decl.py index 66838dd311..153f7c9557 100644 --- a/integration_tests/array_01_decl.py +++ b/integration_tests/array_01_decl.py @@ -1,29 +1,40 @@ -from ltypes import i32, i64, f32, f64, c32, c64 -from numpy import empty +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 + +class ArraySizes(Enum): + SIZE_3: i32 = 3 + SIZE_10: i32 = 10 + +def accept_i16_array(xi16: i16[:]) -> i16: + xi16[2] = i16(32) + return xi16[2] def accept_i32_array(xi32: i32[:]) -> i32: - xi32[0] = 32 - return xi32[0] + xi32[1] = 32 + return xi32[1] def accept_i64_array(xi64: i64[:]) -> i64: - xi64[0] = 64 - return xi64[0] + xi64[1] = i64(64) + return xi64[1] def accept_f32_array(xf32: f32[:]) -> f32: - xf32[0] = 32.0 - return xf32[0] + xf32[1] = f32(32.0) + return xf32[1] def accept_f64_array(xf64: f64[:]) -> f64: xf64[0] = 64.0 return xf64[0] def declare_arrays(): - ai32: i32[3] = empty(3) - ai64: i64[10] = empty(10) - af32: f32[3] = empty(3) - af64: f64[10] = empty(10) - ac32: c32[3] = empty(3) - ac64: c64[10] = empty(10) + ai16: i16[ArraySizes.SIZE_3.value] = empty(ArraySizes.SIZE_3.value, dtype=int16) + ai32: i32[ArraySizes.SIZE_3] = empty(ArraySizes.SIZE_3.value, dtype=int32) + ai64: i64[10] = empty(10, dtype=int64) + af32: f32[3] = empty(3, dtype=float32) + af64: f64[ArraySizes.SIZE_10] = empty(10, dtype=float64) + ac32: c32[ArraySizes.SIZE_3] = empty(3, dtype=complex64) + ac64: c64[10] = empty(10, dtype=complex128) + print(accept_i16_array(ai16)) print(accept_i32_array(ai32)) print(accept_i64_array(ai64)) print(accept_f32_array(af32)) diff --git a/integration_tests/array_02.py b/integration_tests/array_02.py new file mode 100644 index 0000000000..6c9c2ea5c2 --- /dev/null +++ b/integration_tests/array_02.py @@ -0,0 +1,23 @@ +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([45, 60, 20], dtype=int32) + i: i32 + j: i32 + k: i32 + for i in range(Ny): + for j in range(Nx): + for k in range(Nz): + arr[i, j, k] = i * j + k + if k & 1: + arr[i, j, k] = -arr[i, j, k] + + + for i in range(Ny): + for j in range(Nx): + for k in range(Nz): + print(i, j, k, int(arr[i, j, k])) + +main0() 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 new file mode 100644 index 0000000000..9fb02782ca --- /dev/null +++ b/integration_tests/array_03_decl.py @@ -0,0 +1,29 @@ +from lpython import i32, f64, dataclass +from numpy import empty + +@dataclass +class Car: + price: i32 + horsepower: f64 + +@dataclass +class Truck: + price: i32 + wheels: i32 + +def declare_struct_array(): + 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) + + assert cars[0].price == 100000 + assert abs(cars[0].horsepower - 800.0) <= 1e-12 + + assert trucks[0].price == 1000000 + assert trucks[1].price == 5000000 + assert trucks[0].wheels == 8 + assert trucks[1].wheels == 12 + +declare_struct_array() 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 fe6fafd1c4..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) @@ -36,6 +32,6 @@ def array_expr_01(): g = reshape(e + f, shape1d) for i in range(dim1d): - assert abs(g[i] - 2*(i + 1)) <= eps + assert abs(g[i] - f64(2*(i + 1))) <= eps array_expr_01() diff --git a/integration_tests/array_expr_02.py b/integration_tests/array_expr_02.py index 8a2e8cfd03..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]: @@ -10,7 +9,7 @@ def modify(array_a: f32[:], n: i32) -> f32[n]: def verify(array_a: f32[:], array_b: f32[:], result: f32[:], size: i32): i: i32 eps: f32 - eps = 1e-6 + eps = f32(1e-6) for i in range(size): assert abs(array_a[i] * array_a[i] + sqrt(array_b[i]) - result[i]) <= eps @@ -24,12 +23,12 @@ def f(): array_c: f32[256] = empty(256, dtype=float32) for i in range(256): - array_a[i] = float(i) + array_a[i] = f32(i) for j in range(256): - array_b[j] = float(j + 5) + array_b[j] = f32(j + 5) - array_c = array_a**2 + modify(array_b, 256) + array_c = array_a**f32(2) + modify(array_b, 256) verify(array_a, array_b, array_c, 256) 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..8736470c71 --- /dev/null +++ b/integration_tests/array_expr_05.py @@ -0,0 +1,31 @@ +from lpython import u8, u16, u32, u64 +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) + + print(a8) + print(a16) + print(a32) + print(a64) + + 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)) + +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 252e3cb0cf..6b83811264 100644 --- a/integration_tests/bindc_01.py +++ b/integration_tests/bindc_01.py @@ -1,6 +1,14 @@ -from ltypes import c_p_pointer, CPtr, i16 +from lpython import c_p_pointer, CPtr, i16, Pointer, empty_c_void_p -queries: CPtr -x: Pointer[i16] -c_p_pointer(queries, x) +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 6e1f4ac34a..285b8e3085 100644 --- a/integration_tests/bindc_02.py +++ b/integration_tests/bindc_02.py @@ -1,23 +1,23 @@ -from ltypes import c_p_pointer, CPtr, pointer, i16, Pointer +from lpython import c_p_pointer, CPtr, pointer, i16, Pointer, empty_c_void_p +from numpy import empty, int16, array -queries: CPtr -x: Pointer[i16[:]] -c_p_pointer(queries, x) +queries: CPtr = empty_c_void_p() +x: Pointer[i16[:]] = c_p_pointer(queries, i16[:], array([1])) print(queries, x) def f(): - yq: CPtr + yq: CPtr = empty_c_void_p() yptr1: Pointer[i16[:]] - y: i16[2] - y[0] = 1 - y[1] = 2 + y: i16[2] = empty(2, dtype=int16) + y[0] = i16(1) + y[1] = i16(2) yptr1 = pointer(y) print(pointer(y), yptr1) print(yptr1[0], yptr1[1]) - assert yptr1[0] == 1 - assert yptr1[1] == 2 + assert yptr1[0] == i16(1) + assert yptr1[1] == i16(2) - c_p_pointer(yq, yptr1) + yptr1 = c_p_pointer(yq, i16[:], array([2])) print(yq, yptr1) diff --git a/integration_tests/bindc_03.py b/integration_tests/bindc_03.py index 21009607ed..59b1f0efbc 100644 --- a/integration_tests/bindc_03.py +++ b/integration_tests/bindc_03.py @@ -1,10 +1,21 @@ -from ltypes import c_p_pointer, CPtr, pointer, i16, i32, Pointer, ccall, p_c_pointer +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 -@ccall -def g(a: CPtr, value: i32) -> None: +@dataclass +class ArrayWrapped: + array: CPtr + +@ccall(header="bindc_03b.h") +def g(a: CPtr, value: i32, offset_value: bool) -> None: pass -@ccall +def gpy(a: CPtr, value: i32, offset_value: bool) -> None: + g(a, value, offset_value) + +@ccall(header="bindc_03b.h") def get_array(size: i32) -> CPtr: pass @@ -12,22 +23,51 @@ def get_array(size: i32) -> CPtr: def f(q_void: CPtr) -> None: i: i32 el: i32 - q: Pointer[i32[:]] - c_p_pointer(q_void, q) + 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) - g(q2, i * i) + gpy(q2, i * i, bool(i%2)) # TODO: Use q[i] directly in the assert. el = q[i] print(el) - assert el == i * i + assert el == i * i + i%2 + +def h(q_void: CPtr) -> None: + i: i32 + el: 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 = ArrayWrapped() size: i32 size = 10 a = get_array(size) - f(a) + 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_03b.c b/integration_tests/bindc_03b.c index ef987ff8da..463648b54d 100644 --- a/integration_tests/bindc_03b.c +++ b/integration_tests/bindc_03b.c @@ -1,8 +1,12 @@ #include "bindc_03b.h" #include -void g(int32_t* x, int32_t value) { - *x = value; +void g(int32_t* x, int32_t value, bool offset_value) { + if( offset_value ) { + *x = value + 1; + } else { + *x = value; + } } void* get_array(int32_t size) { diff --git a/integration_tests/bindc_03b.h b/integration_tests/bindc_03b.h index 7ff7ce1558..502ac965dd 100644 --- a/integration_tests/bindc_03b.h +++ b/integration_tests/bindc_03b.h @@ -2,8 +2,9 @@ #define BINDC_03B #include +#include -void g(int32_t* x, int32_t value); +void g(int32_t* x, int32_t value, bool offset_value); void* get_array(int32_t size); diff --git a/integration_tests/bindc_04.py b/integration_tests/bindc_04.py index 8bf06b3a20..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[:]] @@ -6,16 +6,16 @@ def f(): yptr1: Pointer[i16[:]] y: i16[2] - y[0] = 1 - y[1] = 2 + y[0] = i16(1) + y[1] = i16(2) yptr1 = pointer(y) - assert yptr1[0] == 1 - assert yptr1[1] == 2 + assert yptr1[0] == i16(1) + assert yptr1[1] == i16(2) x = pointer(y) def check(): f() - assert x[0] == 1 - assert x[1] == 2 + assert x[0] == i16(1) + assert x[1] == i16(2) check() diff --git a/integration_tests/bindc_05.py b/integration_tests/bindc_05.py new file mode 100644 index 0000000000..b01ceee8ba --- /dev/null +++ b/integration_tests/bindc_05.py @@ -0,0 +1,25 @@ +from lpython import CPtr, empty_c_void_p, i32, f32, dataclass, Pointer, ccall, p_c_pointer, pointer + +@dataclass +class Void: + data: CPtr + +@ccall(header="bindc_05b.h") +def trunc_custom(value: Pointer[CPtr]) -> CPtr: + pass + +@ccall(header="bindc_05b.h") +def print_value(value: CPtr): + pass + +def test_trunc(): + float_cptr: CPtr = empty_c_void_p() + float_obj: f32 = f32(1.3) + + p_c_pointer(pointer(float_obj), float_cptr) + voidobj: Void = Void(float_cptr) + voidobj.data = trunc_custom(pointer(voidobj.data)) + + print_value(voidobj.data) + +test_trunc() diff --git a/integration_tests/bindc_05b.c b/integration_tests/bindc_05b.c new file mode 100644 index 0000000000..fd2ff72b95 --- /dev/null +++ b/integration_tests/bindc_05b.c @@ -0,0 +1,13 @@ +#include "bindc_05b.h" +#include + +void* trunc_custom(void** value) { + float* value_float = *value; + int trunced = *value_float; + *value_float = trunced; + return *value; +} + +void print_value(float* value) { + printf("print_value: %f\n", *value); +} diff --git a/integration_tests/bindc_05b.h b/integration_tests/bindc_05b.h new file mode 100644 index 0000000000..95d372053c --- /dev/null +++ b/integration_tests/bindc_05b.h @@ -0,0 +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 new file mode 100644 index 0000000000..d01ca9b800 --- /dev/null +++ b/integration_tests/bindc_06.py @@ -0,0 +1,30 @@ +from lpython import i32, f64, ccall, dataclass +from numpy import empty, int32, float64 + +@dataclass +class CompareOperator: + op_code: i32 + op_name: str + +@ccall(header="bindc_06b.h") +def compare_array_element(value1: i32, value2: f64, op: i32) -> i32: + pass + +def test_arrays(): + array1: i32[40] = empty(40, dtype=int32) + array2: f64[40] = empty(40, dtype=float64) + compare_operator: CompareOperator = CompareOperator(0, "<") + i: i32 + + for i in range(40): + array1[i] = i + 1 + array2[i] = float(2*i + 1) + + is_small: bool = True + for i in range(40): + is_small = is_small and bool(compare_array_element(array1[i], array2[i], compare_operator.op_code)) + + print(is_small) + assert is_small == True + +test_arrays() diff --git a/integration_tests/bindc_06b.c b/integration_tests/bindc_06b.c new file mode 100644 index 0000000000..dee7b006c1 --- /dev/null +++ b/integration_tests/bindc_06b.c @@ -0,0 +1,12 @@ +#include "bindc_06b.h" + +int32_t compare_array_element(int32_t value1, double value2, int32_t code) { + switch( code ) { + case 0: + return value1 <= value2; + case 1: + return value1 >= value2; + default: + return 0; + } +} diff --git a/integration_tests/bindc_06b.h b/integration_tests/bindc_06b.h new file mode 100644 index 0000000000..680d387c7f --- /dev/null +++ b/integration_tests/bindc_06b.h @@ -0,0 +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 new file mode 100644 index 0000000000..f03af3331b --- /dev/null +++ b/integration_tests/bindc_07.py @@ -0,0 +1,68 @@ +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, \ + 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))) + 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, \ + 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[:]] = c_p_pointer(sum_array_cptr, i64[:], array([size])) + i: i32 + + for i in range(size): + iarray1[i] = i8(i) + 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] + 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(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() + 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 new file mode 100644 index 0000000000..7d01f1d279 --- /dev/null +++ b/integration_tests/bit_operations_i32.py @@ -0,0 +1,124 @@ +from lpython import i32 + +def test_bitnot(): + x: i32 = 5 + y: i32 = 0 + z: i32 = 2147483647 + w: i32 = -2147483648 + + p: i32 = ~x + q: i32 = ~y + r: i32 = ~z + s: i32 = ~w + + print(p) + print(q) + print(r) + print(s) + + assert(p == -6) + assert(q == -1) + assert(r == -2147483648) + assert(s == 2147483647) + +def test_bitand(): + x: i32 = 5 + y: i32 = 3 + z: i32 = 2147483647 + w: i32 = -2147483648 + + + p: i32 = x & y + q: i32 = y & z + r: i32 = z & w + s: i32 = x & w + + print(p) + print(q) + print(r) + print(s) + + assert(p == 1) + assert(q == 3) + assert(r == 0) + assert(s == 0) + +def test_bitor(): + x: i32 = 5 + y: i32 = 3 + z: i32 = 2147483647 + w: i32 = -2147483648 + + + p: i32 = x | y + q: i32 = y | z + r: i32 = z | w + s: i32 = x | w + + print(p) + print(q) + print(r) + print(s) + + assert(p == 7) + assert(q == 2147483647) + assert(r == -1) + assert(s == -2147483643) + +def test_bitxor(): + x: i32 = 5 + y: i32 = 3 + z: i32 = 2147483647 + w: i32 = -2147483648 + + + p: i32 = x ^ y + q: i32 = y ^ z + r: i32 = z ^ w + s: i32 = x ^ w + + print(p) + print(q) + print(r) + print(s) + + assert(p == 6) + assert(q == 2147483644) + assert(r == -1) + assert(s == -2147483643) + +def test_left_shift(): + a: i32 = 4 + shift_amount: i32 = 2 + b: i32 = a << shift_amount + print(b) + assert b == 16 + + a = -16 + shift_amount = 2 + b = a << shift_amount + print(b) + assert b == -64 + +def test_right_shift(): + a: i32 = 16 + shift_amount: i32 = 2 + b: i32 = a >> shift_amount + print(b) + assert b == 4 + + a = -16 + shift_amount = 2 + b = a >> shift_amount + print(b) + assert b == -4 + +def main0(): + test_bitnot() + test_bitand() + test_bitor() + test_bitxor() + test_left_shift() + test_right_shift() + +main0() diff --git a/integration_tests/bit_operations_i64.py b/integration_tests/bit_operations_i64.py new file mode 100644 index 0000000000..efc61f6d33 --- /dev/null +++ b/integration_tests/bit_operations_i64.py @@ -0,0 +1,121 @@ +from lpython import i64 + +def test_bitnot(): + x: i64 = i64(123) + y: i64 = i64(456) + z: i64 = i64(115292150460684) + w: i64 = i64(-115292150460685) + + p: i64 = ~x + q: i64 = ~y + r: i64 = ~z + s: i64 = ~w + + print(p) + print(q) + print(r) + print(s) + + assert(p == i64(-124)) + assert(q == i64(-457)) + assert(r == i64(-115292150460685)) + assert(s == i64(115292150460684)) + +def test_bitand(): + x: i64 = i64(741) + y: i64 = i64(982) + z: i64 = i64(115292150460684) + w: i64 = i64(-115292150460685) + + p: i64 = x & y + q: i64 = y & z + r: i64 = z & w + s: i64 = x & w + + print(p) + print(q) + print(r) + print(s) + + assert(p == i64(708)) + assert(q == i64(260)) + assert(r == i64(0)) + assert(s == i64(737)) + +def test_bitor(): + x: i64 = i64(741) + y: i64 = i64(982) + z: i64 = i64(115292150460684) + w: i64 = i64(-115292150460685) + + p: i64 = x | y + q: i64 = y | z + r: i64 = z | w + s: i64 = x | w + + print(p) + print(q) + print(r) + print(s) + + assert(p == i64(1015)) + assert(q == i64(115292150461406)) + assert(r == i64(-1)) + assert(s == i64(-115292150460681)) + +def test_bitxor(): + x: i64 = i64(741) + y: i64 = i64(982) + z: i64 = i64(115292150460684) + w: i64 = i64(-115292150460685) + + p: i64 = x ^ y + q: i64 = y ^ z + r: i64 = z ^ w + s: i64 = x ^ w + + print(p) + print(q) + print(r) + print(s) + + assert(p == i64(307)) + assert(q == i64(115292150461146)) + assert(r == i64(-1)) + assert(s == i64(-115292150461418)) + +def test_left_shift(): + a: i64 = i64(4294967296) + shift_amount: i64 = i64(2) + b: i64 = a << shift_amount + print(b) + assert b == i64(17179869184) + + a = i64(-4294967296) + shift_amount = i64(2) + b = a << shift_amount + print(b) + assert b == i64(-17179869184) + +def test_right_shift(): + a: i64 = i64(4294967296) + shift_amount: i64 = i64(2) + b: i64 = a >> shift_amount + print(b) + assert b == i64(1073741824) + + a = i64(-4294967296) + shift_amount = i64(2) + b = a >> shift_amount + print(b) + assert b == i64(-1073741824) + +def main0(): + test_bitnot() + test_bitand() + test_bitor() + test_bitxor() + test_left_shift() + test_right_shift() + +main0() 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 new file mode 100644 index 0000000000..41ac380a5a --- /dev/null +++ b/integration_tests/comp_01.py @@ -0,0 +1,93 @@ +from lpython import i32, f64 + +def compI32(x: i32, y: i32): + print(x) + print(y) + if x < y: + print("x lt y") + if x > y: + print("x gt y") + if x == y: + print("x eq y") + if x >= y: + print("x ge y") + if x <= y: + print("x le y") + if x != y: + print("x ne y") + +def compF64(x: f64, y: f64): + print(x) + print(y) + if x < y: + print("x lt y") + if x > y: + print("x gt y") + if x == y: + print("x eq y") + if x >= y: + print("x ge y") + if x <= y: + print("x le y") + if x != y: + print("x ne y") + +def test_pos_ints_floats_comp(): + a: i32 = 4 + b: i32 = 5 + c: i32 = 5 + d: i32 = 6 + compI32(a, b) + compI32(b, a) + compI32(a, d) + compI32(b, c) + compI32(c, b) + assert(a < b) + assert(a < d) + assert(b == c) + + x: f64 = 4.555 + y: f64 = 15.55 + w: f64 = 15.55 + z: f64 = 25.12 + compF64(x, y) + compF64(y, x) + compF64(x, z) + compF64(y, w) + compF64(w, y) + assert(x < y) + assert(x < z) + assert(y == w) + +def test_neg_ints_floats_comp(): + a: i32 = -4 + b: i32 = -5 + c: i32 = -5 + d: i32 = -6 + compI32(a, b) + compI32(b, a) + compI32(a, d) + compI32(b, c) + compI32(c, b) + assert(a > b) + assert(a > d) + assert(b == c) + + x: f64 = -4.555 + y: f64 = -15.55 + w: f64 = -15.55 + z: f64 = -25.12 + compF64(x, y) + compF64(y, x) + compF64(x, z) + compF64(y, w) + compF64(w, y) + assert(x > y) + assert(x > z) + assert(y == w) + +def main0(): + test_pos_ints_floats_comp() + test_neg_ints_floats_comp() + +main0() diff --git a/integration_tests/const_01.py b/integration_tests/const_01.py new file mode 100644 index 0000000000..377f3ab676 --- /dev/null +++ b/integration_tests/const_01.py @@ -0,0 +1,26 @@ +from lpython import Const, i32, i64, f32, f64 + +def test_const_variables(): + xci: Const[i32] = i32(0.0) + xi: i32 = 0 + + yci: Const[i64] = int(1) + yi: i64 = int(1) + + xcf: Const[f32] = f32(2) + xf: f32 = f32(2.0) + + 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 + assert ycf == yf + +test_const_variables() diff --git a/integration_tests/const_02.py b/integration_tests/const_02.py new file mode 100644 index 0000000000..b8c69b743c --- /dev/null +++ b/integration_tests/const_02.py @@ -0,0 +1,38 @@ +from lpython import i32, f64, Const + +def f(x: Const[i32]) -> i32: + return x + 1 + +def g(x: Const[i32]) -> Const[f64]: + return float(x + 2) + +def h(x: i32) -> Const[i32]: + return x + 3 + +def test_call_cases(): + y: i32 = 1 + yconst: Const[i32] = 4 + # argument const, parameter non-const + print(h(yconst), f(y), g(yconst)) + assert h(yconst) == 7 + + # argument non-const, parameter const + assert f(y) == 2 + + # argument const, parameter const + assert g(yconst) == 6.0 + +def test_assign_cases(): + y: f64 + yconst: Const[i32] = 4 + # target const, value non-const - error case + + # target non-const, value const + y = g(yconst) + print(y) + assert y == 6.0 + + # target const, value const - error case + +test_call_cases() +test_assign_cases() diff --git a/integration_tests/const_03.py b/integration_tests/const_03.py new file mode 100644 index 0000000000..13d448c0a3 --- /dev/null +++ b/integration_tests/const_03.py @@ -0,0 +1,27 @@ +from lpython import i64, f64, i32, Const, ccall + +CONST_1: Const[f64] = 32.0 +CONST_2: Const[f64] = CONST_1 * 2.0 +CONST_3: Const[i64] = i64(CONST_1 + CONST_2) + +CONST_11: Const[i32] = 32 +CONST_12: Const[i32] = CONST_11 + +def print_value(value: Const[f64]): + print(value) + +@ccall +def print_value_c(value: Const[f64]): + pass + +def test_global_consts(): + print_value(CONST_1) + print_value(CONST_2) + print(CONST_12) + print_value_c(CONST_1) + print_value_c(CONST_2) + assert CONST_1 == 32.0 + assert CONST_2 == 64.0 + assert f64(abs(CONST_3 - i64(96))) < 1e-12 + +test_global_consts() diff --git a/integration_tests/const_03b.c b/integration_tests/const_03b.c new file mode 100644 index 0000000000..d0c37f772b --- /dev/null +++ b/integration_tests/const_03b.c @@ -0,0 +1,6 @@ +#include "const_03b.h" +#include + +void print_value_c(const double value) { + printf("print_value_c: %lf\n", value); +} diff --git a/integration_tests/const_03b.h b/integration_tests/const_03b.h new file mode 100644 index 0000000000..e0d2493696 --- /dev/null +++ b/integration_tests/const_03b.h @@ -0,0 +1 @@ +void print_value_c(const double value); diff --git a/integration_tests/const_04.py b/integration_tests/const_04.py new file mode 100644 index 0000000000..e65b5292fd --- /dev/null +++ b/integration_tests/const_04.py @@ -0,0 +1,18 @@ +from lpython import i32, i16, Const +from numpy import empty, int16 + +def sum_const_array(array: Const[i16[:]], size: i32) -> i16: + i: i32 + array_sum: i16 = i16(0) + for i in range(size): + array_sum += array[i] + return array_sum + +def test_const_array(): + arr: i16[4] = empty(4, dtype=int16) + i: i32 + for i in range(4): + arr[i] = i16(i) + assert sum_const_array(arr, 4) == i16(6) + +test_const_array() 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 8d8cf84277..0a2787c7ed 100644 --- a/integration_tests/elemental_01.py +++ b/integration_tests/elemental_01.py @@ -1,10 +1,10 @@ -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 eps: f32 - eps = 1e-6 + eps = f32(1e-6) for i in range(size): assert abs(sin(sin(array[i])) - result[i]) <= eps @@ -19,7 +19,7 @@ def verifynd(array: f64[:, :, :], result: f64[:, :, :], size1: i32, size2: i32, for i in range(size1): for j in range(size2): for k in range(size3): - assert abs(sin(array[i, j, k])**2 - result[i, j, k]) <= eps + assert abs(sin(array[i, j, k])**2.0 - result[i, j, k]) <= eps def verify2d(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32): i: i32 @@ -29,25 +29,25 @@ def verify2d(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32): for i in range(size1): for j in range(size2): - assert abs(cos(array[i, j])**2 - result[i, j]) <= eps + assert abs(cos(array[i, j])**2.0 - result[i, j]) <= eps 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 + 5*array_b[i]**3 - result[i]) <= eps + assert abs(array_a[i]**2.0 + 5.0*array_b[i]**3.0 - result[i]) <= eps 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 * 5*array_b[i]**3 - result[i]) <= eps + assert abs(array_a[i]**2.0 * 5.0*array_b[i]**3.0 - result[i]) <= eps def elemental_sum(): @@ -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) @@ -65,7 +65,7 @@ def elemental_sum(): for j in range(100): array_b[j] = float(j+5) - array_c = array_a**2 + 5*array_b**3 + array_c = array_a**2.0 + 5.0*array_b**3.0 verify1d_sum(array_a, array_b, array_c, 100) @@ -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) @@ -84,7 +84,7 @@ def elemental_mul(): for j in range(100): array_b[j] = float(j+5) - array_c = array_a**2 * 5*array_b**3 + array_c = array_a**2.0 * 5.0*array_b**3.0 verify1d_mul(array_a, array_b, array_c, 100) @@ -93,40 +93,40 @@ 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] = float(i) + array1d[i] = f32(i) sin1d = sin(sin(array1d)) 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 + 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): array2d[i, j] = float(i + j) - cos2d = cos(array2d)**2 + cos2d = cos(array2d)**2.0 verify2d(array2d, cos2d, 256, 64) @@ -136,30 +136,30 @@ def elemental_trig_identity(): k: i32 l: i32 eps: f32 - eps = 1e-6 + 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): for k in range(8): for l in range(4): - arraynd[i, j, k, l] = float(i + j + k + l) + arraynd[i, j, k, l] = f32(i + j + k + l) - observed = sin(arraynd)**2 + cos(arraynd)**2 + 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) for i in range(65536): - assert abs(observed1d[i] - 1.0) <= eps + assert abs(observed1d[i] - f32(1.0)) <= eps elemental_sin() 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 8a8888f8a2..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,18 +31,18 @@ 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 = 1e-6 + eps = f32(1e-4) for i in range(25): - theta1d[i] = float(i + 1) + theta1d[i] = f32(i + 1) shapend[0] = 5 shapend[1] = 5 diff --git a/integration_tests/elemental_03.py b/integration_tests/elemental_03.py index cd2e7d8f8f..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,37 +20,37 @@ def elemental_sqrt64(): shape[0] = 4096 observed = reshape(sqrt(array), shape) for l in range(4096): - i = int(l/256) + i = i32(l/256) j = (l - i*256)//16 k = (l - i*256 - j*16) - assert abs(observed[l]**2 - i - j - k) <= eps + 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 = 2e-6 + eps = f32(5e-6) i: i32 j: i32 l: i32 for i in range(16): for j in range(16): - array[i, j] = float(i + j) + array[i, j] = f32(i + j) shape[0] = 256 observed = reshape(sqrt(array), shape) for l in range(256): - i = int(l/16) + i = i32(l/16) j = (l - i*16) - assert abs(observed[l]**2 - i - j) <= eps + 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 @@ -61,13 +61,13 @@ def elemental_norm(): for j in range(100): array_b[j] = float(j+5) - array_c = sqrt(array_a**2 + array_b**2) + array_c = sqrt(array_a**2.0 + array_b**2.0) eps: f64 eps = 1e-12 for i in range(100): - assert abs(array_c[i] - sqrt(array_a[i]**2 + array_b[i]**2)) <= eps + assert abs(array_c[i] - sqrt(array_a[i]**2.0 + array_b[i]**2.0)) <= eps elemental_sqrt64() diff --git a/integration_tests/elemental_04.py b/integration_tests/elemental_04.py index 1b3b054012..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 @@ -15,7 +15,7 @@ def elemental_log(): observed = log(array) for i in range(100): - assert abs(exp(observed[i]) - i - 1) <= eps + assert abs(exp(observed[i]) - f64(i + 1)) <= eps def verify(observed: f32[:], base: i32, eps: f32): k: i32 @@ -23,22 +23,22 @@ def verify(observed: f32[:], base: i32, eps: f32): j: i32 for k in range(100): - i = int(k/10) + i = i32(k/10) j = (k - i*10) - assert abs(base**(observed[k]) - i - j - 1) <= eps + 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 = 2e-6 + eps = f32(5e-6) for i in range(10): for j in range(10): - array[i, j] = float(i + j + 1) + array[i, j] = f32(i + j + 1) shape[0] = 100 observed = reshape(log2(array), shape) diff --git a/integration_tests/elemental_05.py b/integration_tests/elemental_05.py index 614298272c..4e91b8eaa2 100644 --- a/integration_tests/elemental_05.py +++ b/integration_tests/elemental_05.py @@ -1,9 +1,9 @@ -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 - eps: f32 = 1e-6 + eps: f32 = f32(1e-6) for i in range(size): assert abs(sinh(sinh(array[i])) - result[i]) <= eps @@ -18,32 +18,32 @@ 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)/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] = i/10.0 + array1d[i] = f32(f64(i)/10.0) 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)/2 + sinhnd = (sinh(arraynd) + 2.0)/2.0 verifynd(arraynd, sinhnd, 40, 10, 16, 2) @@ -53,33 +53,33 @@ def verify2d(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32): for i in range(size1): for j in range(size2): - assert abs(cosh(5 + array[i, j])**2 - result[i, j]) <= eps + assert abs(cosh(5.0 + array[i, j])**2.0 - result[i, j]) <= eps 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 + (array2d))**2 + cosh2d = cosh(5.0 + (array2d))**2.0 verify2d(array2d, cosh2d, 20, 10) 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 + (array2d))**2 + cosh2d = cosh(5.0 + (array2d))**2.0 verify2d(array2d, cosh2d, 20, 10) def elemental_trig_identity(): @@ -104,14 +104,14 @@ def elemental_trig_identity(): for l in range(4): arraynd[i, j, k, l] = sin(float(i + j + k + l)) - identity1 = 1.0 - cosh(arraynd)**2 + sinh(arraynd)**2 - identity2 = cosh(-1 * arraynd) - cosh(arraynd) - identity3 = sinh(-1 * arraynd) + sinh(arraynd) - identity4 = (cosh(arraynd/4 + arraynd/2) - - cosh(arraynd/4) * cosh(arraynd/2) - - sinh(arraynd/4) * sinh(arraynd/2)) + identity1 = 1.0 - cosh(arraynd)**2.0 + sinh(arraynd)**2.0 + identity2 = cosh(-1.0 * arraynd) - cosh(arraynd) + identity3 = sinh(-1.0 * arraynd) + sinh(arraynd) + identity4 = (cosh(arraynd/4.0 + arraynd/2.0) - + 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 26047f06e2..13782bdb14 100644 --- a/integration_tests/elemental_06.py +++ b/integration_tests/elemental_06.py @@ -1,20 +1,20 @@ -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): i: i32 eps: f32 - eps = 1e-6 + eps = f32(1e-6) for i in range(size): assert abs(array[i] - result[i]) <= eps def verify_arcsin_1d(array: f32[:], result: f32[:], size: i32): i: i32 eps: f32 - eps = 1e-6 + eps = f32(1e-6) for i in range(size): - assert abs(arcsin(array[i])**2 - result[i]) <= eps + assert abs(arcsin(array[i])**f32(2.0) - result[i]) <= eps def verify_arcsin_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): i: i32 @@ -23,14 +23,14 @@ def verify_arcsin_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): eps = 1e-12 for i in range(size1): for j in range(size2): - assert abs(arcsin(array[i, j])**2 - result[i, j]) <= eps + assert abs(arcsin(array[i, j])**2.0 - result[i, j]) <= eps def verify_arccos_1d(array: f32[:], result: f32[:], size: i32): i: i32 eps: f32 - eps = 1e-6 + eps = f32(1e-6) for i in range(size): - assert abs(arccos(array[i])**2 - result[i]) <= eps + assert abs(arccos(array[i])**f32(2.0) - result[i]) <= eps def verify_arccos_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): i: i32 @@ -39,14 +39,14 @@ def verify_arccos_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): eps = 1e-12 for i in range(size1): for j in range(size2): - assert abs(arccos(array[i, j])**2 - result[i, j]) <= eps + assert abs(arccos(array[i, j])**2.0 - result[i, j]) <= eps def verify_arctan_1d(array: f32[:], result: f32[:], size: i32): i: i32 eps: f32 - eps = 1e-6 + eps = f32(1e-6) for i in range(size): - assert abs(arctan(array[i])**2 - result[i]) <= eps + assert abs(arctan(array[i])**f32(2.0) - result[i]) <= eps def verify_arctan_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): i: i32 @@ -55,94 +55,103 @@ def verify_arctan_2d(array: f64[:, :], result: f64[:, :], size1:i32, size2:i32): eps = 1e-12 for i in range(size1): for j in range(size2): - assert abs(arctan(array[i, j])**2 - result[i, j]) <= eps + 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] = float((i - 100)/100) - arcsin1d = arcsin(array1d) ** 2 + 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) - arcsin2d = arcsin(array2d) ** 2 + arcsin2d = arcsin(array2d) ** 2.0 verify_arcsin_2d(array2d, arcsin2d, 64, 64) 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] = float((i - 100)/100) - arccos1d = arccos(array1d) ** 2 + 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) - arccos2d = arccos(array2d) ** 2 + arccos2d = arccos(array2d) ** 2.0 verify_arccos_2d(array2d, arccos2d, 64, 64) def elemental_arctan(): i: i32 j: i32 eps: f32 - eps = 1e-6 - array1d: f32[201] = empty(201) - array1d_rec: f32[201] = empty(201) - arctan1d: f32[201] = empty(201) + eps = f32(1e-6) + 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] = float(i-100) - arctan1d = arctan(array1d) ** 2 + array1d[i] = f32(i - 100) + arctan1d = arctan(array1d) ** f32(2.0) verify_arctan_1d(array1d, arctan1d, 201) for i in range(201): - array1d[i] = float(i+1) - array1d_rec[i] = float(1.0/(i+1)) + array1d[i] = f32(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] - pi / 2) <= eps + 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) + array2d[i,j]= float(64*i + j - 2048) - arctan2d = arctan(array2d) ** 2 + arctan2d = arctan(array2d) ** 2.0 verify_arctan_2d(array2d, arctan2d, 64, 64) def elemental_trig_identity(): i: i32 eps: f32 - eps = 1e-6 - array1d: f32[201] = empty(201) - observed1d: f32[201] = empty(201) + eps = f32(1e-6) + array1d: f32[201] = empty(201, dtype=float32) + observed1d: f32[201] = empty(201, dtype=float32) for i in range(201): - array1d[i] = float((i - 100)/100) + array1d[i] = f32((i - 100)/100) observed1d = arcsin(array1d) + arccos(array1d) for i in range(201): - assert abs(observed1d[i] - pi / 2) <= eps + assert abs(observed1d[i] - f32(pi / 2.0)) <= eps 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] = float((i - 100)/100) + array1d[i] = f32((i - 100)/100) observed1d = sin(arcsin(array1d)) verify1d_same(observed1d, array1d, 201) @@ -157,15 +166,15 @@ 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] = float((i - 100)/100) + array1d[i] = f32((i - 100)/100) array_x = sin(arccos(array1d)) array_y = cos(arcsin(array1d)) for i in range(201): - array1d[i] = 1 - array1d[i] ** 2 + array1d[i] = f32(1.0) - array1d[i] ** f32(2.0) array1d = sqrt(array1d) verify1d_same(array_x, array_y, 201) verify1d_same(array_x, array1d, 201) @@ -175,52 +184,81 @@ def elemental_degrees(): j: i32 eps_32: f32 eps_64: f64 - eps_32 = 1e-6 + 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] = float(i) + array1d[i] = f32(i) degrees1d = sin(degrees(array1d)) for i in range(200): - assert abs(degrees1d[i]-sin(degrees(array1d[i]))) <= eps_32 + 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) degrees2d = sin(degrees(array2d)) for i in range(64): for j in range(64): - assert abs(degrees2d[i,j]-sin(degrees(array2d[i,j]))) <= eps_64 + assert abs(degrees2d[i, j] - sin(degrees(array2d[i, j]))) <= eps_64 def elemental_radians(): i: i32 j: i32 eps_32: f32 eps_64: f64 - eps_32 = 1e-6 + 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] = float(i) + array1d[i] = f32(i) radians1d = cos(radians(array1d)) for i in range(200): - assert abs(radians1d[i]-cos(radians(array1d[i]))) <= eps_32 + 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) radians2d = cos(radians(array2d)) for i in range(64): for j in range(64): - assert abs(radians2d[i,j]-cos(radians(array2d[i,j]))) <= eps_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() @@ -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 2bd4faecc9..b458eab989 100644 --- a/integration_tests/elemental_07.py +++ b/integration_tests/elemental_07.py @@ -1,9 +1,9 @@ -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 - eps: f32 = 1e-6 + eps: f32 = f32(1e-6) for i in range(size): assert abs(tanh(sin(array[i])) - result[i]) <= eps @@ -18,32 +18,32 @@ def verifynd(array: f64[:, :, :, :], result: f64[:, :, :, :], size1: i32, size2: result1d: f64[1024] = reshape(result, shape) for i in range(size): - assert abs((tanh(sin(array1d[i])) + 2)/2 - result1d[i]) <= eps + assert abs((tanh(sin(array1d[i])) + 2.0)/2.0 - result1d[i]) <= eps 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] = i / 10.0 + array1d[i] = f32(f64(i) / 10.0) 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)/2 + tanhnd = (tanh(sin(arraynd)) + 2.0)/2.0 verifynd(arraynd, tanhnd, 16, 8, 4, 2) diff --git a/integration_tests/elemental_08.py b/integration_tests/elemental_08.py index d53ad9b00e..1903e93cd1 100644 --- a/integration_tests/elemental_08.py +++ b/integration_tests/elemental_08.py @@ -1,9 +1,9 @@ -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 - eps: f32 = 1e-6 + eps: f32 = f32(1e-6) for i in range(size): assert abs(exp(array[i]) - result[i]) <= eps @@ -18,31 +18,31 @@ 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] = i / 50.0 + array1d[i] = f32(f64(i) / 50.0) 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( i / 8 + j / 4 + k / 2 + 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)) / 2 + expnd = (exp(arraynd) + exp(arraynd / 3.0)) / 2.0 verifynd(arraynd, expnd, 16, 8, 4, 2) diff --git a/integration_tests/elemental_09.py b/integration_tests/elemental_09.py new file mode 100644 index 0000000000..c879d0e926 --- /dev/null +++ b/integration_tests/elemental_09.py @@ -0,0 +1,145 @@ +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 + eps: f32 + eps = f32(1e-6) + + for i in range(size): + assert abs(arcsinh(arcsinh(array[i])) - result[i]) <= eps + +def verifynd_arcsinh(array: f64[:, :, :], result: f64[:, :, :], size1: i32, size2: i32, size3: i32): + i: i32 + j: i32 + k: i32 + eps: f64 + eps = 1e-12 + + for i in range(size1): + for j in range(size2): + for k in range(size3): + assert abs( (1.0 + arcsinh(array[i, j, k])) - result[i, j, k]) <= eps + + +def elemental_arcsinh(): + i: i32 + j: i32 + k: i32 + + array1d: f32[256] = empty(256, dtype=float32) + arcsinh1d: f32[256] = empty(256, dtype=float32) + + for i in range(256): + array1d[i] = f32(i) + + arcsinh1d = arcsinh(arcsinh(array1d)) + verify1d_arcsinh(array1d, arcsinh1d, 256) + + 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(4): + arraynd[i, j, k] = float(i + j + k) + + arcsinhnd = (1.0 + arcsinh(arraynd)) + verifynd_arcsinh(arraynd, arcsinhnd, 256, 64, 4) + +def verify2d_arccosh(array: 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(arccosh(array[i, j])**2.0 - result[i, j]) <= eps + +def verifynd_arccosh(array: f64[:, :, :, :], result: f64[:, :, :, :], size1: i32, size2: i32, size3: i32, size4: i32): + i: i32 + j: i32 + k: i32 + l: i32 + eps: f64 + eps = 1e-12 + + for i in range(size1): + for j in range(size2): + for k in range(size3): + for l in range(size4): + assert abs(100.0 + arccosh(array[i, j, k, l]) / 100.0 - result[i, j, k, l]) <= eps + +def elemental_arccosh(): + i: i32 + j: i32 + k: i32 + l: i32 + + 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): + array2d[i, j] = 2.0 + float(i + j * 2) + + arccosh2d = arccosh(array2d)**2.0 + verify2d_arccosh(array2d, arccosh2d, 256, 64) + + 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): + for k in range(4): + for l in range(2): + arraynd[i, j, k, l] = 2.0 + float(i / 4 + j / 3 + k / 2 + f64(l)) / 100.0 + + arccosh_nd = 100.0 + arccosh(arraynd) / 100.0 + verifynd_arccosh(arraynd, arccosh_nd, 32, 16, 4, 2) + +def elemental_trig_identity(): + i: i32; j: i32; k: i32; l: i32 + eps: f64 = 1e-12 + + arraynd: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + + identity1: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + identity2: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + identity3: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + + + observed1d_1: f64[400] = empty(400, dtype=float64) + observed1d_2: f64[400] = empty(400, dtype=float64) + observed1d_3: f64[400] = empty(400, dtype=float64) + + + for i in range(10): + for j in range(5): + for k in range(2): + for l in range(4): + arraynd[i, j, k, l] = 2.0 + sin((float(i + j + k + l))) + + identity1 = 2.0 * arccosh(arraynd) - arccosh((arraynd**2.0) * 2.0 - 1.0) + identity2 = sinh(arccosh(arraynd)) - sqrt((arraynd**2.0) - 1.0) + identity3 = 2.0 * arcsinh(arraynd) - arccosh((arraynd**2.0) * 2.0 + 1.0) + + + newshape: i32[1] = empty(1, dtype=int32) + newshape[0] = 400 + + observed1d_1 = reshape(identity1, newshape) + observed1d_2 = reshape(identity2, newshape) + observed1d_3 = reshape(identity3, newshape) + + + for i in range(400): + assert abs(observed1d_1[i] - 0.0) <= eps + assert abs(observed1d_2[i] - 0.0) <= eps + assert abs(observed1d_3[i] - 0.0) <= eps + + +elemental_arcsinh() +elemental_arccosh() +elemental_trig_identity() diff --git a/integration_tests/elemental_10.py b/integration_tests/elemental_10.py new file mode 100644 index 0000000000..3583d13806 --- /dev/null +++ b/integration_tests/elemental_10.py @@ -0,0 +1,78 @@ +from lpython import i32, i64, f64 +from numpy import mod, int64, empty + +def test_numpy_mod(): + q1: i64[32, 16, 7] = empty((32, 16, 7), dtype=int64) + d1: i64[32, 16, 7] = empty((32, 16, 7), dtype=int64) + r1: i64[32, 16, 7] = empty((32, 16, 7), dtype=int64) + r1neg: i64[32, 16, 7] = empty((32, 16, 7), dtype=int64) + q2: i64[100] = empty(100, dtype=int64) + d2: i64[100] = empty(100, dtype=int64) + r2: i64[100] = empty(100, dtype=int64) + i: i32; j: i32; k: i32 + rem: i64; q: i64; d: i64 + + for i in range(32): + for j in range(16): + for k in range(7): + d1[i, j, k] = i64(k + 1) + q1[i, j, k] = i64((i + j) * (k + 1) + k) + + r1 = mod(q1, d1) + r1neg = mod(-q1, d1) + + for i in range(32): + for j in range(16): + for k in range(7): + assert r1[i, j, k] == i64(k) + if k == 0: + rem = i64(0) + else: + rem = d1[i, j, k] - i64(k) + assert r1neg[i, j, k] == rem + + for i in range(32): + for j in range(16): + for k in range(7): + d1[i, j, k] = i64(k + 2) + q1[i, j, k] = i64(i + j) + + r1 = mod(d1 * q1 + r1 + i64(1), d1) + + for i in range(32): + for j in range(16): + for k in range(7): + assert r1[i, j, k] == i64(k + 1) + + r1 = mod(i64(2) * q1 + i64(1), int(2)) + + for i in range(32): + for j in range(16): + for k in range(7): + assert r1[i, j, k] == i64(1) + + for i in range(100): + d2[i] = i64(i + 1) + + r2 = mod(int(100), d2) + + for i in range(100): + assert r2[i] == i64(100 % (i + 1)) + + for i in range(100): + d2[i] = i64(50 - i) + q2[i] = i64(39 - i) + + r2 = mod(q2, d2) + + for i in range(100): + d = i64(50 - i) + q = i64(39 - i) + rem = r2[i] + if d == i64(0): + assert rem == i64(0) + else: + assert f64(int((q - rem)/d)) - (q - rem)/d == 0.0 + + +test_numpy_mod() diff --git a/integration_tests/elemental_11.py b/integration_tests/elemental_11.py new file mode 100644 index 0000000000..ca6b111902 --- /dev/null +++ b/integration_tests/elemental_11.py @@ -0,0 +1,85 @@ +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 + eps: f32 + eps = f32(1e-6) + + for i in range(size): + assert abs(arctanh(array[i]) - result[i]) <= eps + +def verifynd_arctanh(array: f64[:, :, :], result: f64[:, :, :], size1: i32, size2: i32, size3: i32): + i: i32 + j: i32 + k: i32 + eps: f64 + eps = 1e-12 + + for i in range(size1): + for j in range(size2): + for k in range(size3): + assert abs( arctanh(array[i, j, k])**2.0 - result[i, j, k]) <= eps + + +def elemental_arctanh(): + i: i32 + j: i32 + k: i32 + + 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)) + + arctanh1d = arctanh(array1d) + verify1d_arctanh(array1d, arctanh1d, 999) + + 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): + for k in range(10): + arraynd[i, j, k] = sin(f64((-1)**k) * float(i + j + k)) + + arctanhnd = arctanh(arraynd)**2.0 + verifynd_arctanh(arraynd, arctanhnd, 100, 50, 10) + + + +def elemental_trig_identity(): + i: i32; j: i32; k: i32; l: i32 + eps: f64 = 1e-12 + + arraynd: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + + identity1: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + identity2: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64) + + observed1d_1: f64[400] = empty(400, dtype=float64) + observed1d_2: f64[400] = empty(400, dtype=float64) + + for i in range(10): + for j in range(5): + for k in range(2): + for l in range(4): + arraynd[i, j, k, l] = ((float(i + j + k + l)))/25.0 + + 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=int32) + newshape[0] = 400 + + observed1d_1 = reshape(identity1, newshape) + observed1d_2 = reshape(identity2, newshape) + + for i in range(400): + assert abs(observed1d_1[i] - 0.0) <= eps + assert abs(observed1d_2[i] - 0.0) <= eps + + +elemental_arctanh() +elemental_trig_identity() diff --git a/integration_tests/elemental_12.py b/integration_tests/elemental_12.py new file mode 100644 index 0000000000..d81baf7293 --- /dev/null +++ b/integration_tests/elemental_12.py @@ -0,0 +1,123 @@ +from lpython import i32, f32, f64 +from numpy import empty, floor, ceil, sqrt, reshape, int32, float32, float64 + +def elemental_floor64(): + 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 + k + l)) + + observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) + observed = floor(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(floor(array[i]) - observed1d[i])) <= eps + + +def elemental_floor32(): + 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 + k + l))) + + observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) + observed = floor(arraynd) + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + assert abs(floor(arraynd[i, j, k, l]) - observed[i, j, k, l]) <= eps + + +def elemental_ceil64(): + 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 + k + l)) + + observed: f64[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float64) + observed = ceil(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(ceil(array[i]) - observed1d[i])) <= eps + + +def elemental_ceil32(): + 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 + k + l))) + + observed: f32[32, 16, 8, 4] = empty((32, 16, 8, 4), dtype=float32) + observed = ceil(arraynd) + + for i in range(32): + for j in range(16): + for k in range(8): + for l in range(4): + assert abs(ceil(arraynd[i, j, k, l]) - observed[i, j, k, l]) <= eps + + +elemental_floor64() +elemental_floor32() +elemental_ceil64() +elemental_ceil32() 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 new file mode 100644 index 0000000000..3c043c767e --- /dev/null +++ b/integration_tests/enum_01.py @@ -0,0 +1,22 @@ +from lpython import i32 +from enum import Enum + +class Color(Enum): + RED: i32 = 1 + GREEN: i32 = 2 + BLUE: i32 = 3 + +def test_color_enum(): + print(Color.RED.value, Color.GREEN.value, Color.BLUE.value) + assert Color.RED.value == 1 + assert Color.GREEN.value == 2 + assert Color.BLUE.value == 3 + +def test_selected_color(selected_color: Color): + color: Color + color = Color(selected_color) + assert color == Color.RED + print(color.name) + +test_color_enum() +test_selected_color(Color.RED) diff --git a/integration_tests/enum_02.py b/integration_tests/enum_02.py new file mode 100644 index 0000000000..c36210d2dd --- /dev/null +++ b/integration_tests/enum_02.py @@ -0,0 +1,39 @@ +from enum import Enum +from lpython import i32, f64 + +class MolecularMass(Enum): + water: i32 = 18 + methane: i32 = 16 + ammonia: i32 = 17 + oxygen: i32 = 16 + +class RelativeCharge(Enum): + proton: i32 = 1 + electron: i32 = -1 + neutron: i32 = 0 + +class AbsoluteChargeWithoutExp(Enum): + proton: f64 = 1.602 # ignoring 10**(-19) because of printing limitations + electron: f64 = -1.602 + neutron: f64 = 0.0 + +def test_mm(): + assert MolecularMass.methane.value == MolecularMass.oxygen.value + assert MolecularMass.ammonia.value - MolecularMass.methane.value == 1 + assert MolecularMass.water.value == MolecularMass.oxygen.value + 2 + +def test_rc(): + assert RelativeCharge.proton.value + RelativeCharge.electron.value == RelativeCharge.neutron.value + +def charge_ratio(c1: AbsoluteChargeWithoutExp, c2: AbsoluteChargeWithoutExp) -> f64: + return c1.value/c2.value + +def test_ac(): + print(AbsoluteChargeWithoutExp.proton.name, AbsoluteChargeWithoutExp.proton.value) + print(AbsoluteChargeWithoutExp.electron.name, AbsoluteChargeWithoutExp.electron.value) + print(AbsoluteChargeWithoutExp.neutron.name, AbsoluteChargeWithoutExp.neutron.value) + assert charge_ratio(AbsoluteChargeWithoutExp.proton, AbsoluteChargeWithoutExp.electron) == -1.0 + +test_mm() +test_rc() +test_ac() diff --git a/integration_tests/enum_03.py b/integration_tests/enum_03.py new file mode 100644 index 0000000000..b087ee7426 --- /dev/null +++ b/integration_tests/enum_03.py @@ -0,0 +1,33 @@ +from enum import Enum +from lpython import i32 + +class NegativeNumbers(Enum): + a: i32 = -1 + b: i32 = -3 + c: i32 = -5 + d: i32 = 0 + e: i32 = 1 + f: i32 = 3 + g: i32 = 5 + +class WholeNumbers(Enum): + h: i32 = 0 + i: i32 = 1 + j: i32 = 3 + k: i32 = 5 + +def test_negative_numbers(): + assert NegativeNumbers.a.value + NegativeNumbers.b.value + NegativeNumbers.c.value == -9 + assert NegativeNumbers.e.value + NegativeNumbers.f.value + NegativeNumbers.g.value == 9 + assert NegativeNumbers.d.value == 0 + +def test_whole_numbers(): + assert WholeNumbers.k.value + WholeNumbers.i.value + WholeNumbers.j.value == 9 + assert WholeNumbers.h.value == 0 + print(WholeNumbers.k.name, WholeNumbers.i.name, WholeNumbers.j.name) + print(WholeNumbers.k.value, WholeNumbers.i.value, WholeNumbers.j.value) + print(WholeNumbers.h.name) + print(WholeNumbers.h.value) + +test_negative_numbers() +test_whole_numbers() diff --git a/integration_tests/enum_04.py b/integration_tests/enum_04.py new file mode 100644 index 0000000000..4b01f3fb79 --- /dev/null +++ b/integration_tests/enum_04.py @@ -0,0 +1,71 @@ +from lpython import i32 +from enum import Enum, auto + +class Color(Enum): + RED: i32 = auto() + GREEN: i32 = auto() + BLUE: i32 = 7 + YELLOW: i32 = auto() + WHITE: i32 = auto() + PINK: i32 = 15 + GREY: i32 = auto() + +class Integers(Enum): + a: i32 = -5 + b: i32 = auto() + c: i32 = auto() + d: i32 = 0 + e: i32 = auto() + f: i32 = 7 + g: i32 = auto() + +def test_color_enum(): + print(Color.RED.value, Color.RED.name) + print(Color.GREEN.value, Color.GREEN.name) + print(Color.BLUE.value, Color.BLUE.name) + print(Color.YELLOW.value, Color.YELLOW.name) + print(Color.WHITE.value, Color.WHITE.name) + print(Color.PINK.value, Color.PINK.name) + print(Color.GREY.value, Color.GREY.name) + assert Color.RED.value == 1 + assert Color.GREEN.value == 2 + assert Color.BLUE.value == 7 + assert Color.YELLOW.value == 8 + assert Color.WHITE.value == 9 + assert Color.PINK.value == 15 + assert Color.GREY.value == 16 + +def test_selected_color(selected_color: Color): + color: Color + color = Color(selected_color) + assert color == Color.YELLOW + print(color.name, color.value) + +def test_integer(integer: Integers, value: i32): + assert integer.value == value + +def test_integers(): + print(Integers.a.name, Integers.a.value) + test_integer(Integers.a, -5) + + print(Integers.b.name, Integers.b.value) + test_integer(Integers.b, -4) + + print(Integers.c.name, Integers.c.value) + test_integer(Integers.c, -3) + + print(Integers.d.name, Integers.d.value) + test_integer(Integers.d, 0) + + print(Integers.e.name, Integers.e.value) + test_integer(Integers.e, 1) + + print(Integers.f.name, Integers.f.value) + test_integer(Integers.f, 7) + + print(Integers.g.name, Integers.g.value) + test_integer(Integers.g, 8) + +test_color_enum() +test_selected_color(Color.YELLOW) +test_integers() diff --git a/integration_tests/enum_05.py b/integration_tests/enum_05.py new file mode 100644 index 0000000000..a3a424e7c9 --- /dev/null +++ b/integration_tests/enum_05.py @@ -0,0 +1,31 @@ +from lpython import i32, ccall +from enum import Enum + +@ccall +class Color(Enum): + RED: i32 = 0 + GREEN: i32 = 1 + BLUE: i32 = 2 + PINK: i32 = 3 + WHITE: i32 = 4 + YELLOW: i32 = 5 + +@ccall +def test_selected_color(selected_color: Color) -> i32: + pass + +def test_colors(): + color: Color = Color(Color.BLUE) + assert test_selected_color(color) == 2 + color = Color(Color.GREEN) + assert test_selected_color(color) == 1 + color = Color(Color.RED) + assert test_selected_color(color) == 0 + color = Color(Color.YELLOW) + assert test_selected_color(color) == 5 + color = Color(Color.WHITE) + assert test_selected_color(color) == 4 + color = Color(Color.PINK) + assert test_selected_color(color) == 3 + +test_colors() diff --git a/integration_tests/enum_05b.c b/integration_tests/enum_05b.c new file mode 100644 index 0000000000..2e729449fd --- /dev/null +++ b/integration_tests/enum_05b.c @@ -0,0 +1,5 @@ +#include "enum_05b.h" + +int32_t test_selected_color(int32_t color) { + return color; +} diff --git a/integration_tests/enum_05b.h b/integration_tests/enum_05b.h new file mode 100644 index 0000000000..817c683673 --- /dev/null +++ b/integration_tests/enum_05b.h @@ -0,0 +1,3 @@ +#include + +int32_t test_selected_color(int32_t); diff --git a/integration_tests/enum_06.py b/integration_tests/enum_06.py new file mode 100644 index 0000000000..e50a0ca0a7 --- /dev/null +++ b/integration_tests/enum_06.py @@ -0,0 +1,35 @@ +from lpython import i32, dataclass, f64 +from numpy import empty +from enum import Enum + +class Color(Enum): + RED: i32 = 0 + GREEN: i32 = 1 + BLUE: i32 = 2 + PINK: i32 = 3 + WHITE: i32 = 4 + YELLOW: i32 = 5 + +@dataclass +class Truck: + horsepower: f64 + seats: i32 + price: f64 + color: Color + +def print_Truck(car: Truck): + print(car.horsepower, car.seats, car.price, car.color.name) + +def test_enum_as_struct_member(): + cars: Truck[3] = empty(3, dtype=Truck) + cars[0] = Truck(700.0, 4, 100000.0, Color.RED) + cars[1] = Truck(800.0, 5, 200000.0, Color.BLUE) + cars[2] = Truck(400.0, 4, 50000.0, Color.WHITE) + print_Truck(cars[0]) + print_Truck(cars[1]) + print_Truck(cars[2]) + assert cars[2].color.value == Color.WHITE.value + assert cars[1].color.value == Color.BLUE.value + assert cars[0].color.value == Color.RED.value + +test_enum_as_struct_member() 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_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 3713f0e9d6..ad46256039 100644 --- a/integration_tests/expr_04.py +++ b/integration_tests/expr_04.py @@ -1,3 +1,4 @@ +from lpython import i32, f32, f64, i64 def main0(): i: i32 sum: i32 @@ -30,12 +31,12 @@ def test_floor_div(): x: f32 eps: f64 eps = 1e-12 - x = 5.0 - assert abs(x//2 - 2) < eps - assert abs(x//2.0 - 2.0) < eps - x = -5.0 - assert abs(x//2 + 3.0) < eps - assert abs(x//2.0 + 3.0) < eps + x = f32(5.0) + assert f64(abs(x//f32(2) - f32(2))) < eps + assert f64(abs(x//f32(2.0) - f32(2.0))) < eps + x = -f32(5.0) + assert f64(abs(x//f32(2) + f32(3.0))) < eps + assert f64(abs(x//f32(2.0) + f32(3.0))) < eps def test_floor_div_9_digits(): # reference: issue 768 @@ -47,9 +48,9 @@ def test_floor_div_9_digits(): x8: i64 y8: i64 - y8 = 10 - x8 = 123456789 - assert x8//y8 == 12345678 + y8 = i64(10) + x8 = i64(123456789) + assert x8//y8 == i64(12345678) def check(): 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 9fc7a83c17..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,11 +11,13 @@ def main0(): b: i32 a = 10 b = -5 + eps: f64 + eps = 1e-12 assert test_multiply(a, b) == -50 i: i64 - i = 1 + i = i64(1) i += int(1) - assert i == 2 + assert i == i64(2) a = 2 b = 5 assert test_mod(a, b) == 2 @@ -52,5 +54,36 @@ def main0(): assert i4 >> 3 == -541 assert -i3 & i4 == -432534758 assert -i3 ^ i4 == 432530657 + a = 10 + a |= 4 + assert a == 14 + a ^= 3 + assert a == 13 + b = 10 + a %= b + assert a == 3 + b = 4 + a <<= b + assert a == 48 + a >>= 1 + assert a == 24 + a &= b + 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 be8fe673bd..566530ddb1 100644 --- a/integration_tests/expr_06.py +++ b/integration_tests/expr_06.py @@ -1,14 +1,14 @@ -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 = (2.0 + 3) * 5.0 - xa: i32[3] = empty(3) + z: f32 = (f32(2.0) + f32(3)) * f32(5.0) + xa: i32[3] = empty(3, dtype=int32) assert x == 25 assert y == 25 - assert z == 25.0 + assert z == f32(25.0) def test_issue_892(): i: i32 @@ -16,16 +16,16 @@ def test_issue_892(): x: i32; p1: f64; p2: f64; y: f64 x = i y = float(x) - p1 = 2*sin(y)*cos(y) - p2 = sin(2*y) + p1 = 2.0*sin(y)*cos(y) + p2 = sin(2.0*y) assert abs(p1 - p2) <= 1e-12 for i in range(1000, 1000 + 100 , 2): x: i32; p1: f64; p2: f64; y: f64 x = i y = float(x) - p1 = sin(y)**2 - p2 = cos(y)**2 + p1 = sin(y)**2.0 + p2 = cos(y)**2.0 assert abs(p1 + p2 - 1.0) <= 1e-12 main0() diff --git a/integration_tests/expr_07.py b/integration_tests/expr_07.py index 55f620384a..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) @@ -10,8 +10,8 @@ def f(): x: i32 = 3 x = 5 b: i32 = x + 1 - assert b == 6 print(a, b) + assert b == 6 g(a*b + 3) diff --git a/integration_tests/expr_08.py b/integration_tests/expr_08.py index 8bf06b3a20..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[:]] @@ -6,16 +6,16 @@ def f(): yptr1: Pointer[i16[:]] y: i16[2] - y[0] = 1 - y[1] = 2 + y[0] = i16(1) + y[1] = i16(2) yptr1 = pointer(y) - assert yptr1[0] == 1 - assert yptr1[1] == 2 + assert yptr1[0] == i16(1) + assert yptr1[1] == i16(2) x = pointer(y) def check(): f() - assert x[0] == 1 - assert x[1] == 2 + assert x[0] == i16(1) + assert x[1] == i16(2) check() diff --git a/integration_tests/expr_09.py b/integration_tests/expr_09.py index db61e98377..a64e5eb35f 100644 --- a/integration_tests/expr_09.py +++ b/integration_tests/expr_09.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32, f64, f32 def main0(): i1: i32 = 10 @@ -11,14 +11,14 @@ def main0(): def test_multiple_assign_1(): a: i32; b: i32; c: i32 - d: f64; e: f32; g: i32 + d: f64; e: f64; g: i32 g = 5 - d = e = g + 1.0 + d = e = f64(g) + 1.0 a = b = c = 10 assert a == b assert b == c assert a == 10 - x: f32; y: f64 + x: f64; y: f64 x = y = 23.0 assert abs(x - 23.0) < 1e-6 assert abs(y - 23.0) < 1e-12 @@ -27,12 +27,12 @@ def test_multiple_assign_1(): i: list[f64]; j: list[f64]; k: list[f64] = [] g = 0 for g in range(10): - k.append(g*2.0 + 5.0) + k.append(f64(g)*2.0 + 5.0) i = j = k for g in range(10): assert abs(i[g] - j[g]) < 1e-12 assert abs(i[g] - k[g]) < 1e-12 - assert abs(g*2.0 + 5.0 - k[g]) < 1e-12 + assert abs(f64(g)*2.0 + 5.0 - k[g]) < 1e-12 def test_issue_928(): 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 d860b310f1..2707f0122f 100644 --- a/integration_tests/expr_12.py +++ b/integration_tests/expr_12.py @@ -1,14 +1,14 @@ -from ltypes import pointer, i16, Pointer +from lpython import pointer, i16, Pointer def g(x: Pointer[i16[:]], y: i16[:]): - y[0] = 1 - y[1] = 2 + y[0] = i16(1) + y[1] = i16(2) x = pointer(y) print(x[0], x[1]) def check(ptr: Pointer[i16[:]]): - assert ptr[0] == 1 - assert ptr[1] == 2 + assert ptr[0] == i16(1) + assert ptr[1] == i16(2) def f(): yptr1: Pointer[i16[:]] diff --git a/integration_tests/expr_13.py b/integration_tests/expr_13.py new file mode 100644 index 0000000000..e9c386f12c --- /dev/null +++ b/integration_tests/expr_13.py @@ -0,0 +1,28 @@ +from lpython import CPtr, empty_c_void_p, i32, Pointer, ccall, Const + +@ccall +def deref_array(x: Pointer[CPtr], idx: i32) -> CPtr: + pass + +@ccall +def get_arrays(num_arrays: i32) -> Pointer[CPtr]: + pass + +@ccall +def sum_array(x: CPtr, size: i32) -> i32: + pass + +def sum_array_python(x: Const[CPtr], size: i32) -> i32: + return sum_array(x, size) + +def test_pointer_to_cptr(): + x: Pointer[CPtr] = empty_c_void_p() + x = get_arrays(2) + i: i32 + sums: i32[2] + for i in range(2): + sums[i] = sum_array_python(deref_array(x, i), 10) + + assert sums[0] == sums[1] + +test_pointer_to_cptr() diff --git a/integration_tests/expr_13b.c b/integration_tests/expr_13b.c new file mode 100644 index 0000000000..2fb9f96d07 --- /dev/null +++ b/integration_tests/expr_13b.c @@ -0,0 +1,24 @@ +#include "expr_13b.h" +#include +#include + +void* deref_array(void** x, int32_t idx) { + return x[idx]; +} + +void** get_arrays(int32_t num_arrays) { + int32_t** mat = malloc(sizeof(int32_t*) * num_arrays); + for (int32_t i = 0; i < num_arrays; i++) { + mat[i] = malloc(sizeof(int32_t) * 10); + } + return (void**) mat; +} + +int32_t sum_array(void* x, int32_t size) { + int32_t* x_int = x; + int32_t sum = 0; + for (int32_t i = 0; i < size; i++) { + sum += x_int[i]; + } + return sum; +} diff --git a/integration_tests/expr_13b.h b/integration_tests/expr_13b.h new file mode 100644 index 0000000000..e6d0cfc0c2 --- /dev/null +++ b/integration_tests/expr_13b.h @@ -0,0 +1,11 @@ + +#ifndef EXPR_13B +#define EXPR_13B + +#include + +void* deref_array(void** x, int32_t idx); +void** get_arrays(int32_t num_arrays); +int32_t sum_array(void* x, int32_t size); + +#endif diff --git a/integration_tests/expr_14.py b/integration_tests/expr_14.py new file mode 100644 index 0000000000..5b22fee92c --- /dev/null +++ b/integration_tests/expr_14.py @@ -0,0 +1,41 @@ +from lpython import i32, i64, f32, f64, c32, c64 + +def test_divide(): + a1: i32; a2: i32; a3: f64; + b1: i64; b2: i64; b3: f64; + c1: f32; c2: f32; c3: f32; + d1: f64; d2: f64; d3: f64; + e1: c32; e2: c32; e3: c32; + f1: c64; f2: c64; f3: c64; + + a1 = 1 + a2 = 9 + a3 = a2/a1 + assert abs(a3 - 9.0) <= 1e-12 + + b1 = i64(2) + b2 = i64(10) + b3 = b2/b1 + assert abs(b3 - 5.0) <= 1e-12 + + c1 = f32(3.0) + c2 = f32(11.0) + c3 = c2/c1 + assert abs(c3 - f32(3.666666)) <= f32(1e-6) + + d1 = 4.0 + d2 = 12.0 + d3 = d2/d1 + assert abs(d3 - 3.0) <= 1e-12 + + e1 = c32(5) + c32(6j) + e2 = c32(13) + c32(14j) + e3 = e2/e1 + assert abs(e3 - c32(2.442622950819672) + c32(0.13114754098360643j)) <= f32(1e-6) + + f1 = c64(7) + 8j + f2 = c64(15) + 16j + f3 = f2/f1 + assert abs(f3 - c64(2.061946902654867) + 0.07079646017699115j) <= 1e-6 + +test_divide() 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 new file mode 100644 index 0000000000..2826e44ea1 --- /dev/null +++ b/integration_tests/float_01.py @@ -0,0 +1,25 @@ +from lpython import f64 + +def sqr(x: f64) -> f64: + return x * x + +def computeCircleArea(radius: f64) -> f64: + pi: f64 = 3.14 + return pi * sqr(radius) + +def main0(): + x: f64 = 213.512 + y: f64 = 55.23 + print(x) + print(y) + print(x + y) + print(x * y) + print(x - y) + print(x / y) + print(computeCircleArea(5.0)) + print(computeMean(2.0, 7.0, 10.0)) + +def computeMean(a: f64, b: f64, c: f64) -> f64: + return (a + b + c) / 3.0 + +main0() 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 new file mode 100644 index 0000000000..1e39f62c6a --- /dev/null +++ b/integration_tests/func_dep_03.py @@ -0,0 +1,21 @@ +from lpython import i32, i64 + +def casti32(x: i64) -> i32: + y: i32 + y = i32(x) + return y + +def casti64(x: i32) -> i64: + return int(x) + +def addi64(x: i32, y: i64) -> i64: + return casti64(x) + y + +def addi32(x: i32, y: i64) -> i32: + return x + casti32(y) + +def test_add(): + assert addi32(5, int(6)) == 11 + assert addi64(7, int(8)) == i64(15) + +test_add() diff --git a/integration_tests/func_dep_04.py b/integration_tests/func_dep_04.py new file mode 100644 index 0000000000..cb464eb716 --- /dev/null +++ b/integration_tests/func_dep_04.py @@ -0,0 +1,13 @@ +from func_dep_04_module import manhattan_distance +from lpython import i32 + +def test_manhattan_distance(): + a: i32; b: i32; c: i32; d: i32; + a = 2 + b = 3 + c = 4 + d = 5 + assert manhattan_distance(a, b, c, d) == 4 + assert manhattan_distance(a, c, b, d) == 2 + +test_manhattan_distance() diff --git a/integration_tests/func_dep_04_module.py b/integration_tests/func_dep_04_module.py new file mode 100644 index 0000000000..570d432088 --- /dev/null +++ b/integration_tests/func_dep_04_module.py @@ -0,0 +1,4 @@ +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 e1a2b473a6..26173b52bd 100644 --- a/integration_tests/func_inline_01.py +++ b/integration_tests/func_inline_01.py @@ -1,16 +1,16 @@ -from ltypes import i64 +from lpython import i64 def fib(n: i64) -> i64: - if n < 2: + if n < i64(2): return n - return fib(n - 1) + fib(n - 2) + return fib(n - i64(1)) + fib(n - i64(2)) def main(): ans: i64 x: i64 - x = 40 + x = i64(40) ans = fib(x) print(ans) - assert ans == 102334155 + assert ans == i64(102334155) main() diff --git a/integration_tests/func_inline_02.py b/integration_tests/func_inline_02.py new file mode 100644 index 0000000000..89331d37a7 --- /dev/null +++ b/integration_tests/func_inline_02.py @@ -0,0 +1,17 @@ +from lpython import i32, Const, inline + +@inline +def f(x: i32) -> i32: + offset: Const[i32] = 1 + return x + offset + +def test_f(): + x: i32 = 0 + x = f(x) + print(x) + assert x == 1 + x = f(x) + print(x) + assert x == 2 + +test_f() 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 new file mode 100644 index 0000000000..c87377f36e --- /dev/null +++ b/integration_tests/func_static_01.py @@ -0,0 +1,15 @@ +from lpython import i64, static + +@static +def fib(n: i64) -> i64: + if n < i64(2): + return n + return fib(n - i64(1)) + fib(n - i64(2)) + +def main0(): + ans: i64; x: i64 + x = i64(5) + ans = fib(x) + assert ans == i64(5) + +main0() diff --git a/integration_tests/func_static_02.py b/integration_tests/func_static_02.py new file mode 100644 index 0000000000..85f8b0151d --- /dev/null +++ b/integration_tests/func_static_02.py @@ -0,0 +1,23 @@ +from lpython import i64, static, inline + +@static +@inline +def fib(n: i64) -> i64: + i: i64; t1: i64; t2: i64; nextTerm: i64; + t1 = int(1) + t2 = int(1) + nextTerm = t1 + t2 + for i in range(int(3), n): + t1 = t2 + t2 = nextTerm + nextTerm = t1 + t2 + return nextTerm + +def main0(): + ans: i64; x: i64 + x = i64(5) + ans = fib(x) + print(ans) + assert ans == i64(5) + +main0() diff --git a/integration_tests/generics_01.py b/integration_tests/generics_01.py index 2b2d1fdc57..c3f1357ade 100644 --- a/integration_tests/generics_01.py +++ b/integration_tests/generics_01.py @@ -1,10 +1,20 @@ -from ltypes import TypeVar, SupportsPlus +from lpython import TypeVar, restriction, i32 -T = TypeVar('T', bound=SupportsPlus) +T = TypeVar('T') -def f(x: T, y: T) -> T: +@restriction +def add(x: T, y: T) -> T: + pass + +def add_integer(x: i32, y: i32) -> i32: + return x + y + +def add_string(x: str, y: str) -> str: return x + y -print(f(1,2)) -print(f("a","b")) -print(f("c","d")) +def f(x: T, y: T, **kwargs) -> T: + return add(x,y) + +print(f(1, 2, add=add_integer)) +print(f("a","b",add=add_string)) +print(f("c","d",add=add_string)) 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 025181db46..3ae77260ee 100644 --- a/integration_tests/generics_array_01.py +++ b/integration_tests/generics_array_01.py @@ -1,4 +1,5 @@ -from ltypes import TypeVar +from lpython import TypeVar, i32 +from numpy import empty, int32 T = TypeVar('T') @@ -8,8 +9,9 @@ def f(lst: T[:], i: T) -> T: def use_array(): array: i32[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 new file mode 100644 index 0000000000..2315582ca0 --- /dev/null +++ b/integration_tests/generics_array_02.py @@ -0,0 +1,37 @@ +from lpython import TypeVar, restriction, i32, f32 +from numpy import empty, int32, float32 + +n = TypeVar("n") +T = TypeVar('T') + +@restriction +def add(x: T, y: T) -> T: + pass + +def add_integer(x: i32, y: i32) -> i32: + return x + y + +def add_float(x: f32, y: f32) -> f32: + return x + y + +def g(n: i32, a: T[n], b: T[n], **kwargs): + r: T[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, dtype=int32) + a_int[0] = 400 + 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, dtype=float32) + a_float[0] = f32(400.0) + b_float: f32[1] = empty(1, dtype=float32) + b_float[0] = f32(20.0) + g(1, a_float, b_float, add=add_float) + +main() diff --git a/integration_tests/generics_array_03.py b/integration_tests/generics_array_03.py new file mode 100644 index 0000000000..ebc5875220 --- /dev/null +++ b/integration_tests/generics_array_03.py @@ -0,0 +1,40 @@ +from lpython import TypeVar, restriction, i32, f32 +from numpy import empty, int32, float32 + +n = TypeVar("n") +m = TypeVar("m") +T = TypeVar('T') + +@restriction +def add(x: T, y: T) -> T: + pass + +def add_integer(x: i32, y: i32) -> i32: + return x + y + +def add_float(x: f32, y: f32) -> f32: + return x + y + +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], dtype=object) + i: i32 + j: i32 + for i in range(n): + for j in range(m): + r[i,j] = add(a[i,j],b[i,j]) + print(r[0,0]) + +def main(): + a_int: i32[1,1] = empty([1,1], dtype=int32) + a_int[0,0] = 400 + 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], dtype=float32) + a_float[0,0] = f32(400) + 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) + +main() diff --git a/integration_tests/generics_list_01.py b/integration_tests/generics_list_01.py index dc83d456fc..2d228532ce 100644 --- a/integration_tests/generics_list_01.py +++ b/integration_tests/generics_list_01.py @@ -1,18 +1,57 @@ -from ltypes import TypeVar, SupportsPlus, SupportsZero, Divisible -from ltypes import f64, i32 +from lpython import TypeVar, f64, i32, restriction -T = TypeVar('T', bound=SupportsPlus|SupportsZero|Divisible) +T = TypeVar('T') -def mean(x: list[T]) -> f64: +@restriction +def zero(x: T) -> T: + pass + +@restriction +def add(x: T, y: T) -> T: + pass + +@restriction +def div(x: T, k: i32) -> f64: + pass + +def empty_integer(x: i32) -> i32: + return 0 + +def add_integer(x: i32, y: i32) -> i32: + return x + y + +def div_integer(x: i32, k: i32) -> f64: + return x / k + +def empty_float(x: f64) -> f64: + return 0.0 + +def add_float(x: f64, y: f64) -> f64: + return x + y + +def div_float(x: f64, k: i32) -> f64: + return x / f64(k) + +def empty_string(x: str) -> str: + return "" + +def add_string(x: str, y: str) -> str: + return x + y + +def div_string(x: str, k: i32) -> f64: + return 0.0 + +def mean(x: list[T], **kwargs) -> f64: k: i32 = len(x) if k == 0: return 0.0 - sum: T - sum = 0 + res: T + res = zero(x[0]) i: i32 for i in range(k): - sum = sum + x[i] - return sum/k + res = add(res, x[i]) + return div(res, k) -print(mean([1,2,3])) -print(mean([1.0,2.0,3.0])) \ No newline at end of file +print(mean([1,2,3], zero=empty_integer, add=add_integer, div=div_integer)) +print(mean([1.0,2.0,3.0], zero=empty_float, add=add_float, div=div_float)) +print(mean(["a","b","c"], zero=empty_string, add=add_string, div=div_string)) \ No newline at end of file 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 new file mode 100644 index 0000000000..dccda55adb --- /dev/null +++ b/integration_tests/if_01.py @@ -0,0 +1,62 @@ +from lpython import i32 + +def Test_if_01(): + z: i32 = 0 + if True: + assert True + + if False: + assert False + + if 1 < 0: + assert False + else: + assert True + + if 1 > 0: + assert True + else: + assert False + + if 1 < 0: + assert False + elif 1 > 0: + assert True + else: + assert False + +def Test_if_02(): + if True: + print(1) + if True: + print(2) + if False: + assert False + elif True: + print(4) + else: + assert False + else: + assert False + + if True: + print(7) + if False: + assert False + if False: + print(9) + else: + print(10) + else: + if True: + print(11) + else: + assert False + print(13) + print(14) + +def Verify(): + Test_if_01() + Test_if_02() + +Verify() diff --git a/integration_tests/if_02.py b/integration_tests/if_02.py new file mode 100644 index 0000000000..2a607f7ae3 --- /dev/null +++ b/integration_tests/if_02.py @@ -0,0 +1,41 @@ +from lpython import i32 + +def test_if_01(): + x: bool = True + y: i32 = 10 + z: i32 = 0 + + if x: + x = False + if x: + z += 1 + else: + z += 1 + + if y > 5: + z += 1 + if y < 12: + z += 1 + if y == 10: + z += 1 + if y != 10: + z += 1 + else: + z += 1 + if y <= 10: + z += 1 + + y = 5 + if y <= 10: + z += 1 + if y >= 5: + z += 1 + if y >= 2: + z += 1 + + assert z == 9 + +def verify(): + test_if_01() + +verify() 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 c6c36b27ae..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 @@ -19,7 +19,7 @@ def test_arg_passing(): arg1 = 1 arg2 = int(2) - arg3 = 3.0 + arg3 = f32(3.0) arg4 = float(4.0) arg5 = complex(5.0, 5.0) arg6 = "testing" 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/integration_tests/lnn/__init__.py b/integration_tests/lnn/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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 new file mode 100644 index 0000000000..4c610e0236 --- /dev/null +++ b/integration_tests/logical_binop1.py @@ -0,0 +1,140 @@ +from lpython import i32 + +def test_issue_1487_1(): # OR operator: a or b + a : i32 + b : i32 + x : i32 + y : i32 + or_op1 : i32 + or_op2 : i32 + a = 1 + b = 2 + x = 0 + y = 4 + or_op1 = a or b + or_op2 = x or y + assert or_op1 == 1 + assert or_op2 == 4 + y = 0 + or_op2 = x or y + assert or_op2 == 0 + + +def test_issue_1487_2(): # AND operator: a and b + a : i32 + b : i32 + x : i32 + y : i32 + and_op1 : i32 + and_op2 : i32 + a = 100 + b = 150 + x = 175 + y = 0 + and_op1 = a and b + and_op2 = y and x + assert and_op1 == 150 + assert and_op2 == 0 + x = 0 + and_op2 = y and x + and_op1 = b and a + assert and_op2 == 0 + assert and_op1 == 100 + + +def test_XOR(): # XOR (exclusive OR) operator: a ^ b + a : i32 + b : i32 + x : i32 + y : i32 + xor_op1 : i32 + xor_op2 : i32 + a = 8 + b = 4 + x = 100 + y = 0 + xor_op1 = b ^ a + xor_op2 = y ^ x + assert xor_op1 == 12 + assert xor_op2 == 100 + + +def test_NOR(): # NOR operator: not(a or b) + a : i32 + b : i32 + x : i32 + y : i32 + nor_op1 : bool + nor_op2 : bool + a = 0 + b = 0 + x = 1 + y = 0 + nor_op1 = not(b or a) + nor_op2 = not(y or x) + assert nor_op1 == True + assert nor_op2 == False + + +def test_NAND(): # NAND operator: not(a and b) + a : i32 + b : i32 + x : i32 + y : i32 + nand_op1 : bool + nand_op2 : bool + a = 0 + b = 0 + x = 1 + y = 1 + nand_op1 = not(b and a) + nand_op2 = not(y and x) + assert nand_op1 == True + assert nand_op2 == False + + +def test_XNOR(): # XNOR operator: == + a : i32 + b : i32 + x : i32 + y : i32 + xnor_op1 : bool + xnor_op2 : bool + a = 0 + b = 0 + x = 1 + y = 0 + xnor_op1 = b == a + xnor_op2 = y == x + assert xnor_op1 == True + assert xnor_op2 == False + + +def test_implies(): # implies operator: <= + a : bool + b : bool + x : bool + y : bool + imp_op1 : bool + imp_op2 : bool + a = True + b = True + x = False + y = True + imp_op1 = b <= a + imp_op2 = y <= x + assert imp_op1 == True + assert imp_op2 == False + + +def check(): + test_issue_1487_1() + test_issue_1487_2() + test_XOR() + test_NOR() + test_NAND() + test_XNOR() + test_implies() + + +check() diff --git a/integration_tests/loop_01.py b/integration_tests/loop_01.py index 1a7ba67ebd..306dc9a09b 100644 --- a/integration_tests/loop_01.py +++ b/integration_tests/loop_01.py @@ -1,13 +1,24 @@ +from lpython import i32, i64, i16 + def main0(): s: str = 'aabbcc'; c: str for c in s: print(c) def test_issue_770(): - i: i64; res: i64 = 0 + i: i32; res: i64 = int(0) for i in range(10): - res += i - assert res == 45 + res += int(i) + assert res == int(45) + +def test_increment(): + i: i16 + sumi: i16 = i16(0) + for i in range(i16(15), i16(-1), i16(-1)): + sumi += i + print(sumi) + assert sumi == i16(120) main0() test_issue_770() +test_increment() diff --git a/integration_tests/loop_02.py b/integration_tests/loop_02.py new file mode 100644 index 0000000000..447ef6e6ad --- /dev/null +++ b/integration_tests/loop_02.py @@ -0,0 +1,96 @@ +from lpython import i32 +def test_loop_01(): + i: i32 = 0 + j: i32 = 0 + + while False: + assert False + + while i < 0: + assert False + + while i < 10: + i += 1 + assert i == 10 + + while i < 20: + while i < 15: + i += 1 + i += 1 + assert i == 20 + + for i in range(5): + assert i == j + j += 1 + +def test_loop_02(): + i: i32 = 0 + j: i32 = 0 + + j = 0 + for i in range(10, 0, -1): + j = j + i + assert j == 55 + + for i in range(5): + if i == 3: + break + assert i == 3 + + j = 0 + for i in range(5): + if i == 3: + continue + j += 1 + assert j == 4 + +def test_loop_03(): + i: i32 = 0 + j: i32 = 0 + k: i32 = 0 + while i < 10: + j = 0 + while j < 10: + k += 1 + if i == 0: + if j == 3: + continue + else: + j += 1 + j += 1 + i += 1 + assert k == 95 + + i = 0; j = 0; k = 0 + while i < 10: + j = 0 + while j < 10: + k += i + j + if i == 5: + if j == 4: + break + else: + j += 1 + j += 1 + i += 1 + assert k == 826 + + i = 0 + if i == 0: + while i < 10: + j = 0 + if j == 0: + while j < 10: + k += 1 + if i == 9: + break + j += 1 + i += 1 + assert k == 917 + +def verify(): + test_loop_01() + test_loop_02() + test_loop_03() + +verify() diff --git a/integration_tests/loop_03.py b/integration_tests/loop_03.py new file mode 100644 index 0000000000..dca553b2ba --- /dev/null +++ b/integration_tests/loop_03.py @@ -0,0 +1,56 @@ +from lpython import i32 + +def test_loop_01(): + i: i32 = 0 + j: i32 = 0 + rt_inc: i32 + rt_inc = 1 + + while False: + assert False + + while i < 0: + assert False + + while i < 10: + i += 1 + assert i == 10 + + while i < 20: + while i < 15: + i += 1 + i += 1 + assert i == 20 + + for i in range(0, 5, rt_inc): + assert i == j + j += 1 + +def test_loop_02(): + i: i32 = 0 + j: i32 = 0 + rt_inc_neg_1: i32 = -1 + rt_inc_1: i32 = 1 + + j = 0 + for i in range(10, 0, rt_inc_neg_1): + j = j + i + assert j == 55 + + for i in range(0, 5, rt_inc_1): + if i == 3: + break + assert i == 3 + + j = 0 + for i in range(0, 5, rt_inc_1): + if i == 3: + continue + j += 1 + assert j == 4 + +def verify(): + test_loop_01() + test_loop_02() + +verify() diff --git a/integration_tests/loop_04.py b/integration_tests/loop_04.py new file mode 100644 index 0000000000..1374a4edc8 --- /dev/null +++ b/integration_tests/loop_04.py @@ -0,0 +1,8 @@ +from lpython import i32 + +j: i32 +i: i32 + +for i in range(5): + j = i + 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 new file mode 100644 index 0000000000..5b53eac8f8 --- /dev/null +++ b/integration_tests/print_02.py @@ -0,0 +1,105 @@ +from lpython import i32, f64 + +# Test: Printing ListConstant +def f(): + 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) + print(b) + print(c) + print(d) + print(a, a, b, c, d) + print(a, a, 1, b, c, 1.1, d) + + # print list constant + print([-3, 2, 1, 0]) + print(['a', 'b', 'c', 'd' , 'e', 'f']) + print([1, 2, 3, 4], a, c) + + +def test_nested_lists(): + w: list[list[list[list[list[f64]]]]] = [[[[[2.13, -98.17]]], [[[1.11]]]]] + x: list[list[list[i32]]] = [[[3, -1], [-2, 5], [5]], [[-3, 1], [2, -5], [-5]]] + y: list[list[f64]] = [[3.14, -1.0012], [-2.38, 5.51]] + z: list[list[str]] = [["bat", "ball"], ["cat", "dog"], ["c", "c++", "java", "python"]] + + print(w) + print(x) + print(y) + print(z) + + +def test_print_list_tuple(): + a: list[tuple[i32, i32]] = [(1, 2), (3, 4), (5, 6)] + b: tuple[list[str], list[i32], f64] + c: list[list[tuple[i32, str]]] = [[(1, 'a'), (2, 'b')], [(3, 'c'), (4, 'd')]] + b1: list[str] = ['a', 'bb', 'ccc', 'dddd', 'eeeee'] + b2: list[i32] = [10, 20, 30, 40] + b = (b1, b2, 6.0305) + print(a, b) + print(c, b1, b2, 3.420, 'okay', True, 14483) + + +def test_nested_lists2(): + # It tests list printing on scale like lists of size (approx) 100. + + # shape = (10, 10), values range from 0 to 99 (both inclusive) + p: list[list[i32]] = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49], [50, 51, 52, 53, 54, 55, 56, 57, 58, 59], [60, 61, 62, 63, 64, 65, 66, 67, 68, 69], [70, 71, 72, 73, 74, 75, 76, 77, 78, 79], [80, 81, 82, 83, 84, 85, 86, 87, 88, 89], [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]] + + # shape = (3, 3, 3, 3), values range between [-101.00, 101.00) + q: list[list[list[list[f64]]]] = [[[[ 74.55, -77.64, 52.35], + [ -78.25, -19.24, 81.38], + [ 7.86, 12.11, 27.5 ]], + + [[ -98.93, -79.62, -73.76], + [ 42.05, -90.29, 69.95], + [ 59.32, -70.78, -53.22]], + + [[ 53.52, -93.88, 49.65], + [ 2.18, 19.91, 69.24], + [ 78.51, 89.69, -86.68]]], + + + [[[ -92.48, -80.75, -27.76], + [ -13.35, 12.28, 79.61], + [ 48.48, -10.49, 41.1 ]], + + [[ 20.33, 14.52, 82.56], + [ -57.76, 76.03, 67.33], + [ -21.5 , -11.92, -31.84]], + + [[ 9.65, 11.15, -36.58], + [ 56.55, -70.85, -50.67], + [ 94.63, 25.68, 89.3 ]]], + + + [[[ 28.53, 71.22, 71.87], + [ -58.39, -6.96, 42.98], + [ -8.95, -75.09, 37.96]], + + [[ -31.75, 67.33, 58.17], + [ -64.01, -9.22, 9.59], + [ 15.71, 82.36, 51.18]], + + [[-100.29, -32.72, -54.94], + [ -0.32, 68.81, -55.09], + [ 97.28, -28.2 , -62.61]]]] + + # shape = (5, 5, 5), where each element is a string of random alphanumerals and length between 0 and 10 + r: list[list[list[str]]] = [[['Io', 'tl', 'bLvjV', 'wjFKQ', 'lY2'], ['Be2l6bqE', 'pQER3utIXA', 'llZBJj5Cdu', 'C8', 'gwTr77PdYR'], ['4M6L', 'ktPdowqERy', 'KSifqTkR', 'ZE2p1N78f1', 'Mi5e87Xw'], ['uwfzqDq9g', 'QaM1s', '', '', 'LB'], ['OJFRY6k', 'iz7Oie', '', 'LUYLF', 'JBND5FuV7l']], [['m', 'WIQBQfV', 'jxjDrqxu', 'kea', 'mu'], ['', 'GI8aOwLMe', 'Y5m8', 'a02Rz', 'xNKCJ'], ['LzkhyiJQHP', 'uzc3xyoXL', 'sKGnYfpRy', '7x', 'WTVKrnPO'], ['TZa6', 'GXRuyRX', 'R', 'JQxS', 'OH'], ['bSVJZ1OQ', 'M', 'I9omlF', 'x7FR', 'XtpL']], [['DKOpK', 'eg8Nz', 'ru', 'Sj', 'YUDxyI'], ['Q5uyhvp', 'Ydx', 'p', 'DLM5RX', 'pwOujxCO'], ['s5GOWnNJV', 'af', 'KAkD', '4IIZK', 'JQK040x'], ['9vF', '9pc7R8v', 'nDReIU7', 'K', 'btn'], ['', 'wVeivkdi', '', '', 'C']], [['vNTtcRXD', 'rsi', 'YsoF7mZD', 'VrPXU50rgA', 'mG7zqN0G'], ['la7cJ', 'M5rLJ8Go', 'gb', 'FjKwYZ7E', 'uSPD'], ['', 'oOa79jWcMx', 'yyAYZZ', 'wbvggXm', 'aE3BkCL4'], ['RdP', 'Hwc0x9RZ', 'sy', '9', 'W1d9xA2BXe'], ['A', '', 'QnK', 'N5tzN', 'ou7Lp']], [['DL68rDF', 'v', 'kQ3Mxm', 'g', '6KTeF4Eo'], ['Hx9', 'Y1IzQm85Z4', '3D8', 'ZLZ5', 'rWn'], ['LtT', 'Dh5B', 'M', 'F', 'QTARbY'], ['Sh', 'WL', 'yvAfWvZSx1', '90yx', 'v'], ['', '7IBW', 'nI', '', '6Cbp5c8RT']]] + + print(p) + print(q) + print(r) + + +def check(): + f() + test_nested_lists() + test_nested_lists2() + test_print_list_tuple() + +check() diff --git a/integration_tests/print_03.py b/integration_tests/print_03.py new file mode 100644 index 0000000000..f421ec0205 --- /dev/null +++ b/integration_tests/print_03.py @@ -0,0 +1,17 @@ +def Main0(): + x: i32 + x = (2+3)* (-5) + y: i32 = 100 + z: i32 = 2147483647 + # w: i32 = -2147483648 # ultimately we should support printing this + w: i32 = -2147483647 + print(x) + print(y) + print(z) + print(w) + print("Hi") + print("Hello") + print((5-2) * 7) + print("Bye") + +Main0() diff --git a/integration_tests/print_04.py b/integration_tests/print_04.py new file mode 100644 index 0000000000..b66175cefc --- /dev/null +++ b/integration_tests/print_04.py @@ -0,0 +1,10 @@ +from lpython import i8, i16, i32, i64 + +u: i64 = i64(-922337203685477580) +print(u) +x: i32 = i32(-2147483648) +print(x) +y: i16 = i16(-32768) +print(y) +z: i8 = i8(-128) +print(z) diff --git a/integration_tests/print_05.py b/integration_tests/print_05.py new file mode 100644 index 0000000000..384d7d7ee9 --- /dev/null +++ b/integration_tests/print_05.py @@ -0,0 +1,16 @@ +def main0(): + print("hi", "1234", "jldakfjs!jdlkasf#9u843*)(") + print("abcdefgh1234") + print(-1234) + print(6579352, -123, "hi", 45897, "bye", 0, -1, 1, -10, 10, "done.") + print("hello") + print(2, -2, 10, -10, 1000, -10000) + + print(3.14) + print(-1000.100) + print(-1000.001) + print("abcdefgh1234") + print(0, 0.0, "abcd", -0, "efghijk", -0.0, "1^3", -1.0, "pqrswxyz", 1.0, "mno", 2.0, "p", -5.1, -5, "zz") + print("pi =", 3.14) + +main0() 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 new file mode 100644 index 0000000000..66ccb3878b --- /dev/null +++ b/integration_tests/print_float.py @@ -0,0 +1,13 @@ +from lpython import f64 + +def main0(): + x: f64 = 0.00012 + y: f64 = -0.00012 + z: f64 = 9255.456 + w: f64 = -9255.456 + print(x) + print(y) + print(z) + print(w) + +main0() 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 new file mode 100644 index 0000000000..b739255654 --- /dev/null +++ b/integration_tests/recursive_01.py @@ -0,0 +1,24 @@ +from lpython import i32 + +def fib(n: i32) -> i32: + if n <= 1: + return n + return fib(n - 1) + fib(n - 2) + +def printNums(n: i32): + if (n == 0): + return + print(n) + printNums(n - 1) + +def main0(): + print("===========================") + i: i32 + for i in range(15): + print(fib(i)) + print("===========================") + print(fib(20)) + print("===========================") + printNums(10) + +main0() diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py new file mode 100755 index 0000000000..e5df7cf909 --- /dev/null +++ b/integration_tests/run_tests.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +import argparse +import subprocess +import os + +# Initialization +DEFAULT_THREADS_TO_USE = 8 # default no of threads is 8 +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}") + process = subprocess.run(cmd, shell=True, cwd=cwd) + if process.returncode != 0: + print(f"Command failed: {cmd}") + exit(1) + + +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} -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) + + +def test_backend(backend): + if backend not in SUPPORTED_BACKENDS: + print(f"Unsupported Backend: {backend}\n") + return + run_test(backend) + + +def get_args(): + parser = argparse.ArgumentParser(description="LPython Integration Test Suite") + 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), default: llvm, cpython" % \ + ", ".join(SUPPORTED_BACKENDS)) + parser.add_argument("-f", "--fast", action='store_true', + help="Run supported tests with --fast") + return parser.parse_args() + + +def main(): + args = get_args() + + # Setup + 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) + + +if __name__ == "__main__": + main() diff --git a/integration_tests/run_tests.sh b/integration_tests/run_tests.sh deleted file mode 100755 index a5ce362ce0..0000000000 --- a/integration_tests/run_tests.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -ex - -rm -rf b1 b2 b3 - -# Append "-j4" or "-j" to run in parallel -jn=$1 - -export PATH="$(pwd)/../src/bin:$PATH" - -mkdir b1 -cd b1 -cmake -DKIND=cpython .. -make $jn -ctest $jn --output-on-failure -cd .. - - -mkdir b2 -cd b2 -cmake -DKIND=llvm .. -make $jn -ctest $jn --output-on-failure -cd .. - -mkdir b3 -cd b3 - -cmake -DKIND=c .. -make $jn -ctest $jn --output-on-failure diff --git a/integration_tests/sizeof_01.py b/integration_tests/sizeof_01.py new file mode 100644 index 0000000000..d6c042b50c --- /dev/null +++ b/integration_tests/sizeof_01.py @@ -0,0 +1,45 @@ +from lpython import sizeof, i64, i32, f32, f64, c32, c64, i16, ccall, CPtr + +@ccall +def cmalloc(bytes: i64) -> CPtr: + pass + +@ccall +def cfree(x: CPtr) -> bool: + pass + +@ccall +def fill_carray(arr: CPtr, size: i32): + pass + +@ccall +def sum_carray(arr: CPtr, size: i32) -> i64: + pass + +def test_sizeof(): + xi16: i16 = i16(0) + xi: i32 = 0 + yi: i64 = i64(0) + xf: f32 = f32(0.0) + yf: f64 = 0.0 + xz: c32 = c32(complex(0, 0)) + yz: c64 = complex(0, 0) + assert sizeof(xi16) == sizeof(i16) + assert sizeof(xi) == sizeof(i32) + assert sizeof(yi) == sizeof(i64) + assert sizeof(xf) == sizeof(f32) + assert sizeof(yf) == sizeof(f64) + assert sizeof(xz) == sizeof(c32) + assert sizeof(yz) == sizeof(c64) + + +def test_c_array(): + summed_up: i64 + carray: CPtr = cmalloc(sizeof(i64) * i64(100)) + fill_carray(carray, 100) + summed_up = sum_carray(carray, 100) + print(summed_up) + assert summed_up == int(5050) + +test_sizeof() +test_c_array() diff --git a/integration_tests/sizeof_01b.c b/integration_tests/sizeof_01b.c new file mode 100644 index 0000000000..8102e1aed5 --- /dev/null +++ b/integration_tests/sizeof_01b.c @@ -0,0 +1,27 @@ +#include "sizeof_01b.h" +#include + +void* cmalloc(int64_t bytes) { + return malloc(bytes); +} + +bool cfree(void* x) { + free(x); + return 1; +} + +void fill_carray(void* arr, int32_t size) { + int64_t* arr_int = arr; + for( int32_t i = 0; i < size; i++ ) { + arr_int[i] = i + 1; + } +} + +int64_t sum_carray(void* arr, int32_t size) { + int64_t* arr_int = arr; + int64_t sum = 0; + for( int32_t i = 0; i < size; i++ ) { + sum += arr_int[i]; + } + return sum; +} diff --git a/integration_tests/sizeof_01b.h b/integration_tests/sizeof_01b.h new file mode 100644 index 0000000000..618fd5b9ba --- /dev/null +++ b/integration_tests/sizeof_01b.h @@ -0,0 +1,8 @@ +#include +#include +#include + +void* cmalloc(int64_t bytes); +bool cfree(void* x); +void fill_carray(void* arr, int32_t size); +int64_t sum_carray(void* arr, int32_t size); 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 8ee2726440..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") @@ -10,5 +12,20 @@ def f(): assert len(x) == 0 x = list("L") assert len(x) == 1 and x[0] == 'L' + x = list(s) + assert len(x) == len(s) + for i in range(len(x)): + assert x[i] == s[i] + s = "agowietg348203wk.smg.afejwp398273wd.a,23to0MEG.F," + x = list(s) + assert len(x) == len(s) + for i in range(len(x)): + assert x[i] == s[i] + s += str(i) + x = list(s) + assert len(x) == len(s) + for i in range(len(x)): + assert x[i] == s[i] + f() diff --git a/integration_tests/structs_01.py b/integration_tests/structs_01.py index 8b63861e0a..7ad860f5f2 100644 --- a/integration_tests/structs_01.py +++ b/integration_tests/structs_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, dataclass +from lpython import i32, f32, f64, dataclass, InOut @dataclass class A: @@ -9,24 +9,23 @@ 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 + 1 + a.y = a.y + f32(1) def g(): - x: A - x = A(3.25, 3) + x: A = A(f32(3.25), 3) f(x) assert x.x == 3 - assert x.y == 3.25 + assert f64(x.y) == 3.25 x.x = 5 - x.y = 5.5 + x.y = f32(5.5) f(x) assert x.x == 5 - assert x.y == 5.5 + assert f64(x.y) == 5.5 change_struct(x) assert x.x == 6 - assert x.y == 6.5 + assert f64(x.y) == 6.5 g() diff --git a/integration_tests/structs_02.py b/integration_tests/structs_02.py index 5dbb4e995a..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 +from lpython import i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer, ccallable, empty_c_void_p, f64 @dataclass class A: @@ -9,20 +9,17 @@ 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, 3.25) a2 = pointer(a1) print(a2, pointer(a1)) x = a2.x y = a2.y assert x == 3 - assert y == 3.25 - c_p_pointer(a, a2) - print(a, a2, pointer(a1)) + assert f64(y) == 3.25 def g(): - b: CPtr + b: CPtr = empty_c_void_p() f(b) g() 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 8b8182114f..aa5e3214e2 100644 --- a/integration_tests/structs_03.py +++ b/integration_tests/structs_03.py @@ -1,4 +1,4 @@ -from ltypes import i32, f32, dataclass, Pointer, pointer +from lpython import i32, f32, f64, dataclass, Pointer, pointer @dataclass class A: @@ -10,12 +10,12 @@ def f(pa: Pointer[A]): print(pa.y) def g(): - x: A = A(3, 3.25) + x: A = A(3, f32(3.25)) xp: Pointer[A] = pointer(x) assert xp.x == 3 - assert xp.y == 3.25 + assert f64(xp.y) == 3.25 xp.x = 5 - xp.y = 5.5 + xp.y = f32(5.5) f(xp) g() diff --git a/integration_tests/structs_04.py b/integration_tests/structs_04.py index 9a0036adc8..b1a1ad4307 100644 --- a/integration_tests/structs_04.py +++ b/integration_tests/structs_04.py @@ -1,4 +1,5 @@ -from ltypes import i32, f32, dataclass +from lpython import i32, f32, f64, dataclass, field +from copy import deepcopy @dataclass class A: @@ -7,27 +8,27 @@ 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) assert b.z == 1 assert b.a.x == 2 - assert b.a.y == 3.0 + assert f64(b.a.y) == 3.0 def g(): - a1: A = A(1.0, 1.0) - a2: A = A(2.0, 2.0) - b: B = B(a1, 1) - b.a = a2 + a1: A = A(f32(1.0), 1) + a2: A = A(f32(2.0), 2) + b: B = B(1, a1) + b.a = deepcopy(a2) b.z = 1 b.a.x = 2 - b.a.y = 3.0 + b.a.y = f32(3.0) assert a1.x == 1 - assert a1.y == 1.0 + assert f64(a1.y) == 1.0 assert a2.x == 2 - assert a2.y == 3.0 + assert f64(a2.y) == 2.0 f(b) g() diff --git a/integration_tests/structs_05.py b/integration_tests/structs_05.py index e5ec3d4dfe..6ae6262ac7 100644 --- a/integration_tests/structs_05.py +++ b/integration_tests/structs_05.py @@ -1,33 +1,58 @@ -from ltypes import i32, f64, dataclass +from lpython import i32, f64, i64, i16, i8, f32, dataclass, InOut, Array +from numpy import empty @dataclass class A: y: f64 x: i32 + z: i64 + a: f32 + b: i16 + 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 - print(s[0].x, s[0].y) - assert s[0].x == x1 - assert abs(s[0].y - y1) < eps - print(s[1].x, s[1].y) - assert s[1].x == x2 - assert abs(s[1].y - y2) < eps + s0: A = s[0] + print(s0.x, s0.y, s0.z, s0.a, s0.b, s0.c, s0.d) + assert s0.x == x1 + assert abs(s0.y - y1) < eps + assert s0.z == i64(x1) + assert abs(s0.a - f32(y1)) < f32(1e-6) + assert s0.b == i16(x1) + assert s0.c == i8(x1) + assert s0.d -def update_1(s: A): + s1: A = s[1] + print(s1.x, s1.y, s1.z, s1.a, s1.b, s1.c, s1.d) + assert s1.x == x2 + assert abs(s1.y - y2) < eps + assert s1.z == i64(x2) + assert abs(s1.a - f32(y2)) < f32(1e-6) + assert s1.b == i16(x2) + assert s1.c == i8(x2) + assert s1.d + +def update_1(s: InOut[A]): s.x = 2 s.y = 1.2 + s.z = i64(2) + s.a = f32(1.2) + 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) + s[1].a = f32(2.3) + s[1].b = i16(3) + 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[0] = A(1.1, 1) - y[1] = A(2.2, 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) update_1(y[0]) update_2(y) diff --git a/integration_tests/structs_06.py b/integration_tests/structs_06.py new file mode 100644 index 0000000000..f82e026cdb --- /dev/null +++ b/integration_tests/structs_06.py @@ -0,0 +1,53 @@ +from lpython import i8, i32, i64, i8, i8, dataclass, packed + +@packed(aligned=1) +@dataclass +class PackedStruct: + Data1: i8 + Data2: i32 + Data3: i8 + Data4: i8 + +@packed(aligned=2) +@dataclass +class PackedStructAligned2: + Data1: i8 + Data2: i32 + Data3: i8 + Data4: i8 + +@packed +@dataclass +class PackedStructUnaligned: + Data1: i8 + Data2: i32 + Data3: i8 + Data4: i8 + +def sum_data(sarg: PackedStruct) -> i64: + return i64(i32(sarg.Data1) + sarg.Data2 + i32(sarg.Data3) + i32(sarg.Data4)) + +def sum_and_product_data(sarg: PackedStructAligned2) -> i64: + product: i64 = i64(i32(sarg.Data1) * sarg.Data2 * i32(sarg.Data3) * i32(sarg.Data4)) + summation: i64 = i64(i32(sarg.Data1) + sarg.Data2 + i32(sarg.Data3) + i32(sarg.Data4)) + return product + summation + +def product_data(sarg: PackedStructUnaligned) -> i64: + return i64(i32(sarg.Data1) * sarg.Data2 * i32(sarg.Data3) * i32(sarg.Data4)) + +def test_sample_struct(): + data1: i8; data2: i32; data3: i8; data4: i8 + data1 = i8(1) + data2 = 2 + data3 = i8(3) + data4 = i8(4) + s: PackedStruct = PackedStruct(data1, data2, data3, data4) + assert sum_data(s) == int(10) + + su: PackedStructUnaligned = PackedStructUnaligned(data1, data2, data3, data4) + assert product_data(su) == int(24) + + su2: PackedStructAligned2 = PackedStructAligned2(data1, data2, data3, data4) + assert sum_and_product_data(su2) == int(34) + +test_sample_struct() diff --git a/integration_tests/structs_07.py b/integration_tests/structs_07.py new file mode 100644 index 0000000000..3d0508ab3a --- /dev/null +++ b/integration_tests/structs_07.py @@ -0,0 +1,21 @@ +from lpython import i32, i64, i8, CPtr, sizeof, dataclass, ccall + +@dataclass +class A: + x: i32 + y: i64 + z: i8 + +@ccall +def cmalloc(bytes: i64) -> CPtr: + pass + +@ccall +def cfree(x: CPtr) -> i32: + pass + +def call_malloc(): + x: CPtr = cmalloc(sizeof(A) * i64(20)) + assert cfree(x) == 1 + +call_malloc() diff --git a/integration_tests/structs_07b.c b/integration_tests/structs_07b.c new file mode 100644 index 0000000000..58a6f0a06c --- /dev/null +++ b/integration_tests/structs_07b.c @@ -0,0 +1,10 @@ +#include "structs_07b.h" + +void* cmalloc(int64_t bytes) { + return malloc(bytes); +} + +bool cfree(void* x) { + free(x); + return 1; +} diff --git a/integration_tests/structs_07b.h b/integration_tests/structs_07b.h new file mode 100644 index 0000000000..ad52616a49 --- /dev/null +++ b/integration_tests/structs_07b.h @@ -0,0 +1,6 @@ +#include +#include +#include + +void* cmalloc(int64_t bytes); +bool cfree(void* x); diff --git a/integration_tests/structs_08.py b/integration_tests/structs_08.py new file mode 100644 index 0000000000..0085334584 --- /dev/null +++ b/integration_tests/structs_08.py @@ -0,0 +1,29 @@ +from lpython import i32, i64, dataclass, union, Union +from enum import Enum + +@union +class B(Union): + x: i32 + y: i64 + +class C(Enum): + RED: i32 = 1 + BLUE: i32 = 5 + WHITE: i32 = 6 + +@dataclass +class A: + b: B + c: i32 + cenum: C + +def test_ordering(): + bd: B = B() + bd.x = 1 + ad: A = A(bd, 2, C.BLUE) + assert ad.b.x == 1 + assert ad.c == 2 + print(ad.cenum.name) + assert ad.cenum.value == 5 + +test_ordering() diff --git a/integration_tests/structs_09.py b/integration_tests/structs_09.py new file mode 100644 index 0000000000..9ba7139cbc --- /dev/null +++ b/integration_tests/structs_09.py @@ -0,0 +1,32 @@ +from lpython import i32, f32, f64, dataclass, field + +@dataclass +class C: + cz: f32 + +@dataclass +class B: + z: i32 + bc: C = field(default_factory=lambda: C(f32(0.0))) + +@dataclass +class A: + y: f32 + x: i32 + b: B = field(default_factory=lambda: B(0, C(f32(0.0)))) + + +def f(a: A): + print(a.x) + print(a.y) + print(a.b.z) + +def g(): + 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 + assert x.b.z == 71 + assert f64(x.b.bc.cz) == 4.0 + +g() diff --git a/integration_tests/structs_10.py b/integration_tests/structs_10.py new file mode 100644 index 0000000000..db067ed825 --- /dev/null +++ b/integration_tests/structs_10.py @@ -0,0 +1,46 @@ +from lpython import i32, f64, dataclass, field +from numpy import empty, float64 + +@dataclass +class Mat: + mat: f64[2, 2] = field(default_factory=lambda: empty((2, 2), dtype=float64)) + +@dataclass +class Vec: + vec: f64[2] = field(default_factory=lambda: empty(2, dtype=float64)) + +@dataclass +class MatVec: + 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) + rotated_vec[0] = mat_vec.mat.mat[0, 0] * mat_vec.vec.vec[0] + mat_vec.mat.mat[0, 1] * mat_vec.vec.vec[1] + rotated_vec[1] = mat_vec.mat.mat[1, 0] * mat_vec.vec.vec[0] + mat_vec.mat.mat[1, 1] * mat_vec.vec.vec[1] + return rotated_vec + +def create_MatVec_obj() -> MatVec: + mat: f64[2, 2] = empty((2, 2), dtype=float64) + vec: f64[2] = empty(2, dtype=float64) + mat[0, 0] = 0.0 + mat[0, 1] = -1.0 + mat[1, 0] = 1.0 + mat[1, 1] = 0.0 + vec[0] = 1.0 + vec[1] = 0.0 + mat_s: Mat = Mat(mat) + vec_s: Vec = Vec(vec) + mat_vec: MatVec = MatVec(mat_s, vec_s) + return mat_vec + +def test_rotate_by_90(): + mat_vec: MatVec = create_MatVec_obj() + print(mat_vec.mat.mat[0, 0], mat_vec.mat.mat[0, 1], mat_vec.mat.mat[1, 0], mat_vec.mat.mat[1, 1]) + print(mat_vec.vec.vec[0], mat_vec.vec.vec[1]) + rotated_vec: f64[2] = rotate(mat_vec) + print(rotated_vec[0], rotated_vec[1]) + assert abs(rotated_vec[0] - 0.0) <= 1e-12 + assert abs(rotated_vec[1] - 1.0) <= 1e-12 + +test_rotate_by_90() diff --git a/integration_tests/structs_11.py b/integration_tests/structs_11.py new file mode 100644 index 0000000000..1eea62eb75 --- /dev/null +++ b/integration_tests/structs_11.py @@ -0,0 +1,18 @@ +from lpython import i32, f64, dataclass + +@dataclass +class A: + x: i32 + y: f64 + +def f(x_: i32, y_: f64) -> A: + a_struct: A = A(x_, y_) + return a_struct + +def test_struct_return(): + b: A = f(0, 1.0) + print(b.x, b.y) + assert b.x == 0 + assert b.y == 1.0 + +test_struct_return() diff --git a/integration_tests/structs_12.py b/integration_tests/structs_12.py new file mode 100644 index 0000000000..c7a2cfb715 --- /dev/null +++ b/integration_tests/structs_12.py @@ -0,0 +1,17 @@ +from lpython import i32, i16, dataclass + +@dataclass +class A: + x: i32 + y: i16 + +def add_A_members(Ax: i32, Ay: i16) -> i32: + return Ax + i32(Ay) + +def test_A_member_passing(): + a: A = A(0, i16(1)) + sum_A_members: i32 = add_A_members(a.x, a.y) + print(sum_A_members) + assert sum_A_members == 1 + +test_A_member_passing() diff --git a/integration_tests/structs_13.py b/integration_tests/structs_13.py new file mode 100644 index 0000000000..9806fa1ac9 --- /dev/null +++ b/integration_tests/structs_13.py @@ -0,0 +1,57 @@ +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 + y: i16 + +@ccall +def cmalloc(size: i64) -> CPtr: + pass + +@ccall +def is_null(ptr: CPtr) -> i32: + pass + +def add_A_members(Ax: i32, Ay: i16) -> i32: + return Ax + i32(Ay) + +@ccall +def add_Aptr_members(Ax: i32, Ay: i16) -> i32: + pass + +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([10])) + i: i32; sum_A_members: i32 + for i in range(10): + array_ptr[i] = A(i, i16(i + 1)) + + for i in range(5): + a: A = array_ptr[i] + sum_A_members = add_A_members(a.x, a.y) + assert a.x == i + assert a.y == i16(i + 1) + print(sum_A_members) + assert sum_A_members == 2*i + 1 + + for i in range(6, 10): + sum_A_members = add_A_members(array_ptr[i].x, array_ptr[i].y) + assert array_ptr[i].x == i + assert array_ptr[i].y == i16(i + 1) + print(sum_A_members) + assert sum_A_members == 2*i + 1 + +def test_Aptr_member_passing(): + a_cptr: CPtr = cmalloc(sizeof(A) * i64(1)) + assert not bool(is_null(a_cptr)), "Failed to allocate array on memory" + a_ptr: Pointer[A] = c_p_pointer(a_cptr, A) + print(add_A_members(a_ptr.x, a_ptr.y), add_Aptr_members(a_ptr.x, a_ptr.y)) + assert add_A_members(a_ptr.x, a_ptr.y) == add_Aptr_members(a_ptr.x, a_ptr.y) + +test_A_member_passing() +test_Aptr_member_passing() diff --git a/integration_tests/structs_13b.c b/integration_tests/structs_13b.c new file mode 100644 index 0000000000..cc22cfca72 --- /dev/null +++ b/integration_tests/structs_13b.c @@ -0,0 +1,13 @@ +#include + +void* cmalloc(int64_t size) { + return malloc(size); +} + +int32_t is_null(void* ptr) { + return ptr == NULL; +} + +int32_t add_Aptr_members(int32_t Ax, int16_t Ay) { + return Ax + Ay; +} diff --git a/integration_tests/structs_13b.h b/integration_tests/structs_13b.h new file mode 100644 index 0000000000..447e72f739 --- /dev/null +++ b/integration_tests/structs_13b.h @@ -0,0 +1,5 @@ +#include + +void* cmalloc(int64_t size); +int32_t is_null(void* ptr); +int32_t add_Aptr_members(int32_t Ax, int16_t Ay); diff --git a/integration_tests/structs_14.py b/integration_tests/structs_14.py new file mode 100644 index 0000000000..911ebc2094 --- /dev/null +++ b/integration_tests/structs_14.py @@ -0,0 +1,108 @@ +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 + +@dataclass +class buffer_struct: + buffer: i8[32] + buffer1: i32[32] + buffer2: f32[32] + buffer3: c32[32] + buffer4: f64[32] + buffer5: i16[32] + buffer6: i64[32] + buffer7: c64[32] + +@ccallable +@packed +@dataclass +class buffer_struct_clink: + buffer: i8[32] + buffer1: i32[32] + buffer2: f32[32] + buffer3: c32[32] + buffer4: f64[32] + buffer5: i16[32] + buffer6: i64[32] + buffer7: c64[32] + +def f(): + i: i32 + buffer_var: i8[32] = empty(32, dtype=int8) + buffer1_var: i32[32] = empty(32, dtype=int32) + buffer2_var: f32[32] = empty(32, dtype=float32) + buffer3_var: c32[32] = empty(32, dtype=complex64) + buffer4_var: f64[32] = empty(32, dtype=float64) + buffer5_var: i16[32] = empty(32, dtype=int16) + buffer6_var: i64[32] = empty(32, dtype=int64) + buffer7_var: c64[32] = empty(32, dtype=complex128) + buffer_: buffer_struct = buffer_struct(deepcopy(buffer_var), deepcopy(buffer1_var), + deepcopy(buffer2_var), deepcopy(buffer3_var), + deepcopy(buffer4_var), deepcopy(buffer5_var), + deepcopy(buffer6_var), deepcopy(buffer7_var)) + buffer_clink_: buffer_struct_clink = buffer_struct_clink(deepcopy(buffer_var), deepcopy(buffer1_var), + deepcopy(buffer2_var), deepcopy(buffer3_var), + deepcopy(buffer4_var), deepcopy(buffer5_var), + deepcopy(buffer6_var), deepcopy(buffer7_var)) + print(buffer_.buffer[15]) + print(buffer_.buffer1[15]) + print(buffer_.buffer2[15]) + print(buffer_.buffer3[15]) + print(buffer_.buffer4[15]) + print(buffer_.buffer5[15]) + print(buffer_.buffer6[15]) + print(buffer_.buffer7[15]) + print(buffer_clink_.buffer[15]) + print(buffer_clink_.buffer1[15]) + print(buffer_clink_.buffer2[15]) + print(buffer_clink_.buffer3[15]) + print(buffer_clink_.buffer4[15]) + print(buffer_clink_.buffer5[15]) + print(buffer_clink_.buffer6[15]) + print(buffer_clink_.buffer7[15]) + + for i in range(32): + buffer_.buffer[i] = i8(i + 1) + buffer_clink_.buffer[i] = i8(i + 2) + buffer_.buffer1[i] = i32(i + 3) + buffer_clink_.buffer1[i] = i32(i + 4) + buffer_.buffer2[i] = f32(i + 5) + buffer_clink_.buffer2[i] = f32(i + 6) + buffer_.buffer3[i] = c32(i + 7) + # buffer_clink_.buffer3 is a ctypes.Array + # of type c_float_complex (a ctypes.Structure + # 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. + # buffer_clink_.buffer3[i] = c32(i + 8) + buffer_.buffer4[i] = f64(i + 9) + buffer_clink_.buffer4[i] = f64(i + 10) + buffer_.buffer5[i] = i16(i + 11) + buffer_clink_.buffer5[i] = i16(i + 12) + buffer_.buffer6[i] = i64(i + 13) + buffer_clink_.buffer6[i] = i64(i + 14) + buffer_.buffer7[i] = c64(i + 15) + # buffer_clink_.buffer7[i] = c64(i + 16) + + for i in range(32): + print(i, buffer_.buffer[i], buffer_clink_.buffer[i]) + print(i, buffer_clink_.buffer1[i], buffer_.buffer1[i]) + print(i, buffer_clink_.buffer2[i], buffer_.buffer2[i]) + print(i, buffer_clink_.buffer3[i], buffer_.buffer3[i]) + print(i, buffer_clink_.buffer4[i], buffer_.buffer4[i]) + print(i, buffer_clink_.buffer5[i], buffer_.buffer5[i]) + print(i, buffer_clink_.buffer6[i], buffer_.buffer6[i]) + print(i, buffer_clink_.buffer7[i], buffer_.buffer7[i]) + assert buffer_.buffer[i] == i8(i + 1) + assert buffer_clink_.buffer[i] == i8(i + 2) + assert buffer_clink_.buffer[i] - buffer_.buffer[i] == i8(1) + assert buffer_clink_.buffer1[i] - buffer_.buffer1[i] == i32(1) + assert buffer_clink_.buffer2[i] - buffer_.buffer2[i] == f32(1) + # assert buffer_clink_.buffer3[i] - buffer_.buffer3[i] == c32(1) + assert buffer_clink_.buffer4[i] - buffer_.buffer4[i] == f64(1) + assert buffer_clink_.buffer5[i] - buffer_.buffer5[i] == i16(1) + assert buffer_clink_.buffer6[i] - buffer_.buffer6[i] == i64(1) + # assert buffer_clink_.buffer7[i] - buffer_.buffer7[i] == c64(1) + +f() diff --git a/integration_tests/structs_15.py b/integration_tests/structs_15.py new file mode 100644 index 0000000000..7341d42d60 --- /dev/null +++ b/integration_tests/structs_15.py @@ -0,0 +1,42 @@ +from lpython import i32, i16, i8, CPtr, dataclass, ccall, Pointer, c_p_pointer, sizeof, ccallable + +@ccallable +@dataclass +class A: + x: i16 + y: i8 + +@ccall +def _lfortran_malloc(size: i32) -> CPtr: + pass + +@ccall +def _lfortran_memset(cptr: CPtr, value: i32, size: i32): + pass + +def add_A_members(Ax: i16, Ay: i8) -> i16: + return Ax + i16(Ay) + +def test_Aptr_member_passing(): + print(sizeof(A)) + + a_cptr: CPtr = _lfortran_malloc(i32(sizeof(A))) + _lfortran_memset(a_cptr, 2, i32(sizeof(A))) + b_cptr: CPtr = _lfortran_malloc(i32(sizeof(A))) + _lfortran_memset(b_cptr, 6, i32(sizeof(A))) + + a_ptr: Pointer[A] = c_p_pointer(a_cptr, A) + b_ptr: Pointer[A] = c_p_pointer(b_cptr, A) + print(a_ptr.x, a_ptr.y) + print(b_ptr.x, b_ptr.y) + assert a_ptr.x * i16(3) == b_ptr.x + assert a_ptr.y * i8(3) == b_ptr.y + + a_ptr.y = i8(-18) + assert a_ptr.x * i16(3) == b_ptr.x + a_ptr.x = i16(20) + print(a_ptr.x, a_ptr.y) + print(add_A_members(a_ptr.x, a_ptr.y)) + assert add_A_members(a_ptr.x, a_ptr.y) == i16(2) + +test_Aptr_member_passing() diff --git a/integration_tests/structs_16.py b/integration_tests/structs_16.py new file mode 100644 index 0000000000..6cf6e638d5 --- /dev/null +++ b/integration_tests/structs_16.py @@ -0,0 +1,19 @@ +from lpython import i32, i64, dataclass, union, Union + +@dataclass +class A: + @union + class B(Union): + x: i32 + y: i64 + b: B + c: i32 + +def test_ordering(): + bd: A.B = A.B() + bd.x = 1 + ad: A = A(bd, 2) + assert ad.b.x == 1 + assert ad.c == 2 + +test_ordering() diff --git a/integration_tests/structs_17.py b/integration_tests/structs_17.py new file mode 100644 index 0000000000..30042f68f7 --- /dev/null +++ b/integration_tests/structs_17.py @@ -0,0 +1,31 @@ +from lpython import i32, f32, f64, dataclass, field + +@dataclass +class B: + z: i32 + @dataclass + class C: + cz: f32 + bc: C = field(default_factory=lambda: C(f32(0.0))) + +@dataclass +class A: + y: f32 + x: i32 + b: B = field(default_factory=lambda: B(0, B.C(f32(0.0)))) + + +def f(a: A): + print(a.x) + print(a.y) + print(a.b.z) + +def g(): + x: A = A(f32(3.25), 3, B(71, B.C(f32(4.0)))) + f(x) + assert x.x == 3 + assert f64(x.y) == 3.25 + assert x.b.z == 71 + assert f64(x.b.bc.cz) == 4.0 + +g() diff --git a/integration_tests/structs_18.py b/integration_tests/structs_18.py new file mode 100644 index 0000000000..d6a5fbd66b --- /dev/null +++ b/integration_tests/structs_18.py @@ -0,0 +1,110 @@ +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 + +@packed +@dataclass +class buffer_struct: + buffer8: i8[32] + buffer1: i32[32] + buffer2: f32[32] + buffer3: c32[32] + buffer4: f64[32] + buffer5: i16[32] + buffer6: i64[32] + buffer7: c64[32] + +@ccallable +@packed +@dataclass +class buffer_struct_clink: + buffer8: i8[32] + buffer1: i32[32] + buffer2: f32[32] + buffer3: c32[32] + buffer4: f64[32] + buffer5: i16[32] + buffer6: i64[32] + buffer7: c64[32] + +@ccall +def sum_buffer_i16(arr: i16[:], size: i32) -> i16: + pass + +@ccall +def fill_buffer(buffer_cptr: CPtr): + pass + +def f(): + i: i32 + buffer8_var: i8[32] = empty(32, dtype=int8) + buffer1_var: i32[32] = empty(32, dtype=int32) + buffer2_var: f32[32] = empty(32, dtype=float32) + buffer3_var: c32[32] = empty(32, dtype=complex64) + buffer4_var: f64[32] = empty(32, dtype=float64) + buffer5_var: i16[32] = empty(32, dtype=int16) + buffer6_var: i64[32] = empty(32, dtype=int64) + buffer7_var: c64[32] = empty(32, dtype=complex128) + buffer_: buffer_struct = buffer_struct(deepcopy(buffer8_var), deepcopy(buffer1_var), + deepcopy(buffer2_var), deepcopy(buffer3_var), + deepcopy(buffer4_var), deepcopy(buffer5_var), + deepcopy(buffer6_var), deepcopy(buffer7_var)) + buffer_clink_: buffer_struct_clink = buffer_struct_clink(deepcopy(buffer8_var), deepcopy(buffer1_var), + deepcopy(buffer2_var), deepcopy(buffer3_var), + deepcopy(buffer4_var), deepcopy(buffer5_var), + deepcopy(buffer6_var), deepcopy(buffer7_var)) + buffer_clink_cptr: CPtr = empty_c_void_p() + print(buffer_.buffer8[15]) + print(buffer_.buffer1[15]) + print(buffer_.buffer2[15]) + print(buffer_.buffer3[15]) + print(buffer_.buffer4[15]) + print(buffer_.buffer5[15]) + print(buffer_.buffer6[15]) + print(buffer_.buffer7[15]) + print(buffer_clink_.buffer8[15]) + print(buffer_clink_.buffer1[15]) + print(buffer_clink_.buffer2[15]) + print(buffer_clink_.buffer3[15]) + print(buffer_clink_.buffer4[15]) + print(buffer_clink_.buffer5[15]) + print(buffer_clink_.buffer6[15]) + print(buffer_clink_.buffer7[15]) + + p_c_pointer(pointer(buffer_clink_), buffer_clink_cptr) + fill_buffer(buffer_clink_cptr) + + for i in range(32): + buffer_.buffer8[i] = i8(i + 1) + buffer_.buffer1[i] = i32(i + 3) + buffer_.buffer2[i] = f32(i + 5) + buffer_.buffer3[i] = c32(i + 7) + buffer_.buffer4[i] = f64(i + 9) + buffer_.buffer5[i] = i16(i + 11) + buffer_.buffer6[i] = i64(i + 13) + buffer_.buffer7[i] = c64(i + 15) + + for i in range(32): + print(i, buffer_.buffer8[i], buffer_clink_.buffer8[i]) + print(i, buffer_clink_.buffer1[i], buffer_.buffer1[i]) + print(i, buffer_clink_.buffer2[i], buffer_.buffer2[i]) + print(i, buffer_clink_.buffer3[i], buffer_.buffer3[i]) + print(i, buffer_clink_.buffer4[i], buffer_.buffer4[i]) + print(i, buffer_clink_.buffer5[i], buffer_.buffer5[i]) + print(i, buffer_clink_.buffer6[i], buffer_.buffer6[i]) + print(i, buffer_clink_.buffer7[i], buffer_.buffer7[i]) + assert buffer_.buffer8[i] == i8(i + 1) + assert buffer_clink_.buffer8[i] == i8(i + 2) + assert buffer_clink_.buffer8[i] - buffer_.buffer8[i] == i8(1) + assert buffer_clink_.buffer1[i] - buffer_.buffer1[i] == i32(1) + assert buffer_clink_.buffer2[i] - buffer_.buffer2[i] == f32(1) + assert buffer_clink_.buffer3[i] - buffer_.buffer3[i] == c32(1) + assert buffer_clink_.buffer4[i] - buffer_.buffer4[i] == f64(1) + assert buffer_clink_.buffer5[i] - buffer_.buffer5[i] == i16(1) + assert buffer_clink_.buffer6[i] - buffer_.buffer6[i] == i64(1) + assert buffer_clink_.buffer7[i] - buffer_.buffer7[i] == c64(1) + + print(sum_buffer_i16(buffer_.buffer5, 32)) + assert sum_buffer_i16(buffer_clink_.buffer5, 32) == i16(880) + +f() diff --git a/integration_tests/structs_18b.c b/integration_tests/structs_18b.c new file mode 100644 index 0000000000..fb24bd5934 --- /dev/null +++ b/integration_tests/structs_18b.c @@ -0,0 +1,35 @@ +#include "structs_18b.h" +#include + +int16_t sum_buffer_i16(int16_t data[], int32_t size) { + int16_t sum_buffer = 0; + for( int32_t i = 0; i < size; i++ ) { + sum_buffer += data[i]; + } + return sum_buffer; +} + +struct __attribute__((packed)) buffer_c { + int8_t buffer8[32]; + int32_t buffer1[32]; + float buffer2[32]; + float complex buffer3[32]; + double buffer4[32]; + int16_t buffer5[32]; + int64_t buffer6[32]; + double complex buffer7[32]; +}; + +void fill_buffer(void* buffer_cptr) { + struct buffer_c* buffer_clink_ = (struct buffer_c*) buffer_cptr; + for(int32_t i = 0; i < 32; i++) { + buffer_clink_->buffer8[i] = i + 2; + buffer_clink_->buffer1[i] = i + 4; + buffer_clink_->buffer2[i] = i + 6; + buffer_clink_->buffer3[i] = CMPLXF(i + 8, 0); + buffer_clink_->buffer4[i] = i + 10; + buffer_clink_->buffer5[i] = i + 12; + buffer_clink_->buffer6[i] = i + 14; + buffer_clink_->buffer7[i] = CMPLXL(i + 16, 0); + } +} diff --git a/integration_tests/structs_18b.h b/integration_tests/structs_18b.h new file mode 100644 index 0000000000..693344f55c --- /dev/null +++ b/integration_tests/structs_18b.h @@ -0,0 +1,4 @@ +#include + +int16_t sum_buffer_i16(int16_t data[], int32_t size); +void fill_buffer(void* buffer_cptr); diff --git a/integration_tests/structs_19.py b/integration_tests/structs_19.py new file mode 100644 index 0000000000..1ae675eb81 --- /dev/null +++ b/integration_tests/structs_19.py @@ -0,0 +1,130 @@ +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 + +@ccallable +@dataclass +class buffer_struct: + buffer8: i8 + buffer1: i32 + buffer2: f32 + buffer3: c32 + buffer4: f64 + buffer5: i16 + buffer6: i64 + buffer7: c64 + +@ccallable +@dataclass +class buffer_struct_array: + buffer8: i8[25] + buffer1: i32[16] + buffer2: f32[16] + buffer4: f64[16] + buffer5: i16[32] + buffer6: i64[8] + buffer3: c32[8] + buffer7: c64[4] + +@ccall +def get_buffer() -> CPtr: + pass + +@ccall +def fill_buffer(buffer_cptr: CPtr): + pass + +@ccall +def get_buffer_array() -> CPtr: + pass + +@ccall +def fill_buffer_array(buffer_cptr: CPtr): + pass + +def f(): + b: CPtr = get_buffer() + pb: Pointer[buffer_struct] = c_p_pointer(b, buffer_struct) + pb.buffer8 = i8(3) + pb.buffer1 = i32(4) + pb.buffer2 = f32(5) + pb.buffer3 = c32(9) + pb.buffer4 = f64(6) + pb.buffer5 = i16(7) + pb.buffer6 = i64(8) + pb.buffer7 = c64(10) + print(pb.buffer8) + print(pb.buffer1) + print(pb.buffer2) + print(pb.buffer3) + print(pb.buffer4) + print(pb.buffer5) + print(pb.buffer6) + print(pb.buffer7) + assert pb.buffer8 == i8(3) + assert pb.buffer1 == i32(4) + assert pb.buffer2 == f32(5) + assert pb.buffer3 == c32(9) + assert pb.buffer4 == f64(6) + assert pb.buffer5 == i16(7) + assert pb.buffer6 == i64(8) + assert pb.buffer7 == c64(10) + + fill_buffer(b) + print(pb.buffer8) + print(pb.buffer1) + print(pb.buffer2) + print(pb.buffer3) + print(pb.buffer4) + print(pb.buffer5) + print(pb.buffer6) + print(pb.buffer7) + assert pb.buffer8 == i8(8) + assert pb.buffer1 == i32(9) + assert pb.buffer2 == f32(10) + assert pb.buffer3 == c32(14) + c32(15j) + assert pb.buffer4 == f64(11) + assert pb.buffer5 == i16(12) + assert pb.buffer6 == i64(13) + assert pb.buffer7 == c64(16) + c64(17j) + +def f_array(): + i: i32 + b: CPtr = get_buffer_array() + pb: Pointer[buffer_struct_array] = c_p_pointer(b, buffer_struct_array) + pb.buffer8 = empty(25, dtype=int8) + pb.buffer1 = empty(16, dtype=int32) + pb.buffer2 = empty(16, dtype=float32) + pb.buffer4 = empty(16, dtype=float64) + pb.buffer5 = empty(32, dtype=int16) + pb.buffer6 = empty(8, dtype=int64) + pb.buffer3 = empty(8, dtype=complex64) + pb.buffer7 = empty(4, dtype=complex128) + + fill_buffer_array(b) + for i in range(25): + print(pb.buffer8[i]) + assert pb.buffer8[i] == i8(i + 8) + + for i in range(16): + print(pb.buffer1[i], pb.buffer2[i], pb.buffer4[i]) + assert pb.buffer1[i] == i32(i + 1) + assert pb.buffer2[i] == f32(i + 2) + assert pb.buffer4[i] == f64(i + 4) + + for i in range(32): + print(pb.buffer5[i]) + assert pb.buffer5[i] == i16(i + 5) + + for i in range(8): + print(pb.buffer6[i], pb.buffer3[i]) + assert pb.buffer6[i] == i64(i + 6) + assert pb.buffer3[i] == c32(i + 3) + + for i in range(4): + print(pb.buffer7[i]) + assert pb.buffer7[i] == c64(i + 7) + + +f() +f_array() diff --git a/integration_tests/structs_19b.c b/integration_tests/structs_19b.c new file mode 100644 index 0000000000..57626d1c90 --- /dev/null +++ b/integration_tests/structs_19b.c @@ -0,0 +1,68 @@ +#include +#include +#include "structs_19b.h" + + +struct buffer_c { + int8_t buffer8; + int32_t buffer1; + float buffer2; + float complex buffer3; + double buffer4; + int16_t buffer5; + int64_t buffer6; + double complex buffer7; +}; + +void fill_buffer(void* buffer_cptr) { + struct buffer_c* buffer_clink_ = (struct buffer_c*) buffer_cptr; + buffer_clink_->buffer8 = 8; + buffer_clink_->buffer1 = 9; + buffer_clink_->buffer2 = 10.0; + buffer_clink_->buffer3 = CMPLXF(14.0, 15.0); + buffer_clink_->buffer4 = 11.0; + buffer_clink_->buffer5 = 12; + buffer_clink_->buffer6 = 13; + buffer_clink_->buffer7 = CMPLXL(16.0, 17.0); +} + +struct buffer_c_array { + int8_t buffer8[25]; + int32_t buffer1[16]; + float buffer2[16]; + double buffer4[16]; + int16_t buffer5[32]; + int64_t buffer6[8]; + float complex buffer3[8]; + double complex buffer7[4]; +}; + +void fill_buffer_array(void* buffer_cptr) { + struct buffer_c_array* buffer_clink_ = (struct buffer_c_array*) buffer_cptr; + for( int i = 0; i < 25; i++ ) { + buffer_clink_->buffer8[i] = i + 8; + } + for( int i = 0; i < 16; i++ ) { + buffer_clink_->buffer1[i] = i + 1; + buffer_clink_->buffer2[i] = i + 2; + buffer_clink_->buffer4[i] = i + 4; + } + for( int i = 0; i < 32; i++ ) { + buffer_clink_->buffer5[i] = i + 5; + } + for( int i = 0; i < 8; i++ ) { + buffer_clink_->buffer6[i] = i + 6; + buffer_clink_->buffer3[i] = CMPLXF(i + 3, 0.0); + } + for( int i = 0; i < 4; i++ ) { + buffer_clink_->buffer7[i] = CMPLXL(i + 7, 0.0); + } +} + +void* get_buffer() { + return malloc(sizeof(struct buffer_c)); +} + +void* get_buffer_array() { + return malloc(sizeof(struct buffer_c_array)); +} diff --git a/integration_tests/structs_19b.h b/integration_tests/structs_19b.h new file mode 100644 index 0000000000..738ef9f980 --- /dev/null +++ b/integration_tests/structs_19b.h @@ -0,0 +1,6 @@ +#include + +void fill_buffer(void* buffer_cptr); +void fill_buffer_array(void* buffer_cptr); +void* get_buffer(); +void* get_buffer_array(); diff --git a/integration_tests/structs_20.py b/integration_tests/structs_20.py new file mode 100644 index 0000000000..0b26bb6398 --- /dev/null +++ b/integration_tests/structs_20.py @@ -0,0 +1,58 @@ +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 + +@ccallable +@packed +@dataclass +class buffer_struct_packed: + buffer8: i8[32] + buffer1: i16[32] + buffer2: i32 + buffer3: f32[32] + buffer4: f64 + buffer5: c32[32] + buffer6: c64 + +@ccall +def get_buffer() -> CPtr: + pass + +@ccall +def fill_buffer(buffer_cptr: CPtr): + pass + +def f(): + i: i32 + b: CPtr = get_buffer() + pb: Pointer[buffer_struct_packed] = c_p_pointer(b, buffer_struct_packed) + pb.buffer8 = empty(32, dtype=int8) + pb.buffer1 = empty(32, dtype=int16) + pb.buffer2 = i32(5) + pb.buffer3 = empty(32, dtype=float32) + pb.buffer4 = f64(6) + pb.buffer5 = empty(32, dtype=complex64) + pb.buffer6 = c64(8) + print(pb.buffer2) + print(pb.buffer4) + print(pb.buffer6) + assert pb.buffer2 == i32(5) + assert pb.buffer4 == f64(6) + assert pb.buffer6 == c64(8) + + fill_buffer(b) + print(pb.buffer2) + print(pb.buffer4) + print(pb.buffer6) + assert pb.buffer2 == i32(3) + assert pb.buffer4 == f64(5) + assert pb.buffer6 == c64(7) + + for i in range(32): + print(pb.buffer8[i], pb.buffer1[i], pb.buffer3[i], pb.buffer5[i]) + assert pb.buffer8[i] == i8(i + 8) + assert pb.buffer1[i] == i16(i + 1) + assert pb.buffer3[i] == f32(i + 3) + assert pb.buffer5[i] == c32(i + 5) + +f() diff --git a/integration_tests/structs_20b.c b/integration_tests/structs_20b.c new file mode 100644 index 0000000000..596cad2bda --- /dev/null +++ b/integration_tests/structs_20b.c @@ -0,0 +1,37 @@ +#include +#include +#include "structs_20b.h" + + +struct __attribute__((packed)) buffer_c_packed { + int8_t buffer8[32]; + int16_t buffer1[32]; + int32_t buffer2; + float buffer3[32]; + double buffer4; + float complex buffer5[32]; + double complex buffer6; +}; + +void fill_buffer(void* buffer_cptr) { + struct buffer_c_packed* buffer_clink_ = (struct buffer_c_packed*) buffer_cptr; + for( int i = 0; i < 32; i++ ) { + buffer_clink_->buffer8[i] = i + 8; + } + for( int i = 0; i < 32; i++ ) { + buffer_clink_->buffer1[i] = i + 1; + } + buffer_clink_->buffer2 = 3; + for( int i = 0; i < 32; i++ ) { + buffer_clink_->buffer3[i] = i + 3; + } + buffer_clink_->buffer4 = 5; + for( int i = 0; i < 32; i++ ) { + buffer_clink_->buffer5[i] = CMPLXF(i + 5, 0.0); + } + buffer_clink_->buffer6 = CMPLXL(7, 0.0); +} + +void* get_buffer() { + return malloc(sizeof(struct buffer_c_packed)); +} diff --git a/integration_tests/structs_20b.h b/integration_tests/structs_20b.h new file mode 100644 index 0000000000..d047988c57 --- /dev/null +++ b/integration_tests/structs_20b.h @@ -0,0 +1,4 @@ +#include + +void fill_buffer(void* buffer_cptr); +void* get_buffer(); diff --git a/integration_tests/structs_21.py b/integration_tests/structs_21.py new file mode 100644 index 0000000000..26d83aee39 --- /dev/null +++ b/integration_tests/structs_21.py @@ -0,0 +1,36 @@ +from lpython import i32, CPtr, dataclass, c_p_pointer, p_c_pointer, \ + pointer, empty_c_void_p, Pointer, ccallable + +@ccallable +@dataclass +class S: + a: i32 + +def f(c: CPtr): + # The following two lines are the actual test: we take an argument `c` of + # type CPtr, convert to type Pointer[S] and access the member `a`. This + # tests that the order of initialization is preserved in the generated LLVM + # or C code. + p: Pointer[S] = c_p_pointer(c, S) + A: i32 = p.a + + # We check that we get the expected result: + 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_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 new file mode 100644 index 0000000000..c7ba747072 --- /dev/null +++ b/integration_tests/test_argv_01.py @@ -0,0 +1,22 @@ +from lpython import i32 +from sys import argv + +def test(): + exe: str = argv[0] + res: str = "" + + if exe[0] == '.': + exe = exe[1:len(exe)] + + s: str + for s in exe: + if s == '.': + break + 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 d10e72660d..8c64a4682d 100644 --- a/integration_tests/test_bit_length.py +++ b/integration_tests/test_bit_length.py @@ -1,4 +1,6 @@ from math import floor, log2 +from lpython import i8, i32, i16 + def ff(): assert -8 .bit_length() == -4 #TODO:(1 << 12).bit_length() @@ -12,18 +14,35 @@ def ff1(): def ff2(): x: i8 - x = 1 << 6 - assert x.bit_length() == 7 + x = i8(1 << 6) + assert i32(x.bit_length()) == 7 def ff3(): x: i16 one: i16 - one = 1 - x = -(one << 13) - assert x.bit_length() == 14 + one = i16(1) + 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 74e409a4ae..e869e8f060 100644 --- a/integration_tests/test_bool_binop.py +++ b/integration_tests/test_bool_binop.py @@ -1,29 +1,29 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def f(): i: i32 - i = True + True + i = i32(True + True) assert i == 2 - i = True - False + i = i32(True - False) assert i == 1 - i = False * True + i = i32(False * True) assert i == 0 - i = True // True + i = i32(True // True) assert i == 1 - i = False // True + i = i32(False // True) assert i == 0 - i = True ** True + i = i32(True ** True) assert i == 1 f: f64 b1: bool = False b2: bool = True - f = b1/b2 + f = f64(b1/b2) assert f == 0.0 f() 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 d94a28a11b..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 @@ -10,8 +10,8 @@ def test_abs(): assert abs(-5.5) == 5.5 x2: f32 - x2 = -5.5 - assert abs(x2) == 5.5 + x2 = -f32(5.5) + assert abs(x2) == f32(5.5) i: i32 i = -5 @@ -19,21 +19,21 @@ def test_abs(): assert abs(-1) == 1 i2: i64 - i2 = -6 - assert abs(i2) == 6 + i2 = -i64(6) + assert abs(i2) == i64(6) i3: i8 - i3 = -7 - assert abs(i3) == 7 + i3 = -i8(7) + assert abs(i3) == i8(7) i4: i16 - i4 = -8 - assert abs(i4) == 8 + i4 = -i16(8) + assert abs(i4) == i16(8) 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 cebb20a995..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 +from lpython import i8, i16, i32, i64, f32, f64, c32, c64 def test_bool(): a: i32 @@ -10,15 +10,15 @@ def test_bool(): assert not bool(0) a2: i64 - a2 = 34 + a2 = i64(34) assert bool(a2) a3: i8 - a3 = 34 + a3 = i8(34) assert bool(a3) a4: i16 - a4 = -1 + a4 = -i16(1) assert bool(a4) f: f64 @@ -30,10 +30,10 @@ def test_bool(): assert not bool(0.0) f2: f32 - f2 = -235.6 + f2 = -f32(235.6) assert bool(f2) - f2 = 0.0000534 + f2 = f32(0.0000534) assert bool(f2) s: str @@ -53,17 +53,17 @@ def test_bool(): assert not bool(False) c: c32 - c = complex(2, 3) + c = c32(complex(2, 3)) assert bool(c) - c = complex(0, 0) + c = c32(complex(0, 0)) assert not bool(c) - assert not bool(0 + 0j) + assert not bool(c64(0) + 0j) c1: c64 c1 = complex(0, 0.100202) assert bool(c1) assert not bool(complex(0, 0)) - assert bool(3 + 5j) + assert bool(c64(3) + 5j) test_bool() 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 4aea73f182..9b28b0b61a 100644 --- a/integration_tests/test_builtin_float.py +++ b/integration_tests/test_builtin_float.py @@ -1,10 +1,10 @@ -from ltypes import i32, f32, f64 +from lpython import i32, f32, f64 def test_float(): i: i32 i = 34 f: f32 - f = 0.0 + f = f32(0.0) assert float() == 0.0 assert float(34) == 34.0 assert float(i) == 34.0 @@ -23,6 +23,6 @@ def test_float(): f2 = float(b) assert f2 == 1.0 b = False - assert b == 0.0 + assert f64(b) == 0.0 test_float() 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 fd82f40a02..248a82c100 100644 --- a/integration_tests/test_builtin_int.py +++ b/integration_tests/test_builtin_int.py @@ -1,47 +1,48 @@ -from ltypes import f64, i32, i64 +from lpython import f64, i32, i64 def test_int(): f: f64 f = 5.678 i: i32 i = 4 - assert int() == 0 - assert int(i) == 4 + assert int() == i64(0) + assert int(i) == i64(4) i2: i64 i2 = int(3.0) - assert i2 == 3 - assert int(5.678) == 5 - assert int(f) == 5 + assert i2 == i64(3) + assert int(5.678) == i64(5) + assert int(f) == i64(5) f = -183745.23 - assert int(-183745.23) == -183745 - assert int(f) == -183745 - assert int(5.5) == 5 - assert int(-5.5) == -5 - assert int(True) == 1 - assert int(False) == 0 + assert int(-183745.23) == i64(-183745) + assert int(f) == i64(-183745) + assert int(5.5) == i64(5) + assert int(-5.5) == i64(-5) + assert int(True) == i64(1) + assert int(False) == i64(0) def test_bool_to_int(): b: i32 - b = True - True + b = i32(True - True) assert b == 0 - b = False - False + b = i32(False - False) assert b == 0 - b = False - True + b = i32(False - True) assert b == -1 - b = True - False + b = i32(True - False) assert b == 1 - b = True + True + b = i32(True + True) assert b == 2 - b = False + False + b = i32(False + False) assert b == 0 - b = False + True + b = i32(False + True) assert b == 1 - b = True + False + b = i32(True + False) assert b == 1 - b = True + True + True - False + b = i32(True + True) + i32(True - False) + print(b) assert b == 3 - b = True + (True + True) - (False + True) + b = i32(True) + i32(True + True) - i32(False + True) assert b == 2 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 d9497340e0..4ee87579e3 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 @@ -8,13 +8,13 @@ def test_pow(): eps = 1e-12 a = 2 b = 5 - assert pow(a, b) == 32 + assert i32(pow(a, b)) == 32 a = 6 b = 3 - assert pow(a, b) == 216 + assert i32(pow(a, b)) == 216 a = 2 b = 0 - assert pow(a, b) == 1 + assert i32(pow(a, b)) == 1 a = 2 b = -1 # assert abs(pow(a, b) - 0.5) < eps @@ -24,18 +24,18 @@ def test_pow(): i1: i64 i2: i64 - i1 = 2 - i2 = 5 - assert pow(i1, i2) == 32 - i1 = 6 - i2 = -3 + i1 = i64(2) + i2 = i64(5) + assert i64(pow(i1, i2)) == i64(32) + i1 = i64(6) + i2 = -i64(3) # assert abs(pow(i1, i2) - 0.004629629629629629) < eps f1: f32 f2: f32 p: f32 - f1 = 525346/66456 - f2 = 3.0 + f1 = f32(525346/66456) + f2 = f32(3.0) p = pow(f1, f2) f1 = pow(a, f2) # (i32, f32) @@ -59,10 +59,10 @@ def test_pow(): assert abs(pow(y, x) - 12.166999999999998) < eps assert abs(pow(x, 5.5) - 420.8883462392372) < eps - assert abs(pow(2, -1) - 0.5) < eps - assert abs(pow(6, -4) - 0.0007716049382716049) < eps - assert abs(pow(-3, -5) + 0.00411522633744856) < eps - assert abs(pow(6, -4) - 0.0007716049382716049) < eps + assert abs(pow(i64(2), -i64(1)) - 0.5) < eps + assert abs(pow(i64(6), -i64(4)) - 0.0007716049382716049) < eps + assert abs(pow(-i64(3), -i64(5)) + 0.00411522633744856) < eps + assert abs(pow(i64(6), -i64(4)) - 0.0007716049382716049) < eps assert abs(pow(4.5, 2.3) - 31.7971929089206) < eps assert abs(pow(2.3, 0.0) - 1.0) < eps assert abs(pow(2.3, -1.5) - 0.2866871623459944) < eps @@ -70,20 +70,20 @@ def test_pow(): assert abs(pow(2, -3.4) - 0.09473228540689989) < eps assert abs(pow(3.4, 9) - 60716.99276646398) < eps assert abs(pow(0.0, 53) - 0.0) < eps - assert pow(4, 2) == 16 + assert i32(pow(4, 2)) == 16 assert abs(pow(-4235.0, 52) - 3.948003805985264e+188) < eps i: i64 - i = 7 + i = i64(7) j: i64 - j = 2 + j = i64(2) k: i64 - k = 5 - assert pow(i, j, k) == 4 + k = i64(5) + assert pow(i, j, k) == i64(4) assert pow(102, 3, 121) == 38 c1: c32 - c1 = complex(4, 5) + c1 = c32(complex(4, 5)) c1 = pow(c1, 4) test_pow() diff --git a/integration_tests/test_builtin_round.py b/integration_tests/test_builtin_round.py index 1afad84791..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 @@ -23,7 +23,7 @@ def test_round(): assert round(56.78) == 57 f2: f32 - f2 = 5.678 + f2 = f32(5.678) assert round(f2) == 6 i: i32 @@ -32,16 +32,16 @@ def test_round(): assert round(4) == 4 i2: i8 - i2 = 7 - assert round(i2) == 7 + i2 = i8(7) + assert round(i2) == i8(7) i3: i16 - i3 = -8 - assert round(i3) == -8 + i3 = i16(-8) + assert round(i3) == i16(-8) i4: i64 - i4 = 0 - assert round(i4) == 0 + i4 = i64(0) + assert round(i4) == i64(0) b: bool b = True diff --git a/integration_tests/test_builtin_str.py b/integration_tests/test_builtin_str.py index f346f790d7..bf3c1c106f 100644 --- a/integration_tests/test_builtin_str.py +++ b/integration_tests/test_builtin_str.py @@ -1,4 +1,6 @@ -def test_str_int(): +from lpython import f32, f64, i32 + +def test_str_int_float(): s: str s = str(356) assert s == "356" @@ -11,7 +13,7 @@ def test_str_int(): assert str(False) == "False" assert str(True) == "True" assert str("just a str") == "just a str" - assert str(12.1234) == "12.1234" + assert str(12.1234)[:7] == "12.1234" def str_conv_for_variables(): x: i32 @@ -24,7 +26,7 @@ def str_conv_for_variables(): x = -121212 assert "-121212" == str(x) xx: f32 - xx = 12.322234 + xx = f32(12.322234) assert str(xx) == "12.322234" yy : f64 yy = 12.322234 @@ -48,30 +50,42 @@ def test_str_slice_step(): start = 1 end = 4 step = 1 - assert s[3:12:3] == "dgj" - assert s[3:9:3] == "dg" - assert s[10:3:-2] == "kige" + + # Check all possible combinations assert s[::] == "abcdefghijk" assert s[1:4:] == "bcd" assert s[:4:5] == "a" + assert s[::-1] == "kjihgfedcba" + assert s[3:12:3] == "dgj" + assert s[1::3] == "behk" + assert s[4::] == "efghijk" + assert s[:5:] == "abcde" + + assert s[3:9:3] == "dg" + assert s[10:3:-2] == "kige" assert s[-2:-10] == "" assert s[-3:-9:-3] == "if" assert s[-3:-10:-3] == "ifc" assert s[start:end:step] == "bcd" assert s[start:2*end-3:step] == "bcde" assert s[start:2*end-3:-step] == "" - assert s[::-1] == "kjihgfedcba" + def test_issue_883(): s: str s = "abcde" c: str + d: str + d = "edcba" + i: i32 = 0 for c in s[::-1]: print(c) + assert c == d[i] + i += 1 -test_str_int() +test_str_int_float() str_conv_for_variables() test_str_slice_step() test_issue_883() 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 4a79213b07..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,28 +9,15 @@ 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 def test_c_callbacks(): pi: f64 = 3.141592653589793238462643383279502884197 - assert abs(_lfortran_dsin(pi) - 0) < 1e-12 - assert abs(_lfortran_dsin(pi/2) - 1) < 1e-12 - assert abs(_lfortran_ssin(pi) - 0) < 1e-6 - assert abs(_lfortran_ssin(pi/2) - 1) < 1e-6 - - assert _lfortran_bgt32(3, 4) == 0 - assert _lfortran_bgt32(4, 3) == 1 - assert _lfortran_bgt64(3, 4) == 0 - assert _lfortran_bgt64(4, 3) == 1 + assert abs(_lfortran_dsin(pi) - 0.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) test_c_callbacks() diff --git a/integration_tests/test_c_interop_02.py b/integration_tests/test_c_interop_02.py index c2e5ed4bba..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: @@ -31,27 +31,27 @@ def f_str_i32(x: str) -> i32: def test_c_callbacks(): xf64: f64 xf64 = 3.3 - assert abs(f_f64_f64(xf64) - (xf64+1)) < 1e-12 + assert abs(f_f64_f64(xf64) - (xf64 + 1.0)) < 1e-12 xf32: f32 - xf32 = 3.3 - assert abs(f_f32_f32(xf32) - (xf32+1)) < 1e-6 + xf32 = f32(3.3) + assert abs(f_f32_f32(xf32) - (xf32 + f32(1))) < f32(1e-6) xi64: i64 - xi64 = 3 - assert f_i64_i64(xi64) == 4 + xi64 = i64(3) + assert f_i64_i64(xi64) == i64(4) xi32: i32 xi32 = 3 assert f_i32_i32(xi32) == 4 xi16: i16 - xi16 = 3 - assert f_i16_i16(xi16) == 4 + xi16 = i16(3) + assert f_i16_i16(xi16) == i16(4) xi8: i8 - xi8 = 3 - assert f_i8_i8(xi8) == 4 + xi8 = i8(3) + assert f_i8_i8(xi8) == i8(4) assert f_str_i32("Hello World!") == 12 assert f_str_i32("abc") == 3 diff --git a/integration_tests/test_c_interop_03.py b/integration_tests/test_c_interop_03.py index 3243524a57..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 @@ -32,18 +32,18 @@ def test_c_callbacks(): assert f_pi32_i32(f_pvoid_pvoid(p)) == 4 xi64: i64 - xi64 = 3 + xi64 = i64(3) p_c_pointer(pointer(xi64, i64), p) print(pointer(xi64, i64), p) - assert f_pi64_i32(p) == 4 - assert f_pi64_i32(f_pvoid_pvoid(p)) == 4 + assert f_pi64_i32(p) == i64(4) + assert f_pi64_i32(f_pvoid_pvoid(p)) == i64(4) xf32: f32 - xf32 = 3.3 + xf32 = f32(3.3) p_c_pointer(pointer(xf32, f32), p) print(pointer(xf32, f32), p) - assert abs(f_pf32_i32(p)-4.3) < 1e-6 - assert abs(f_pf32_i32(f_pvoid_pvoid(p))-4.3) < 1e-6 + assert abs(f_pf32_i32(p) - f32(4.3)) < f32(1e-6) + assert abs(f_pf32_i32(f_pvoid_pvoid(p)) - f32(4.3)) < f32(1e-6) xf64: f64 xf64 = 3.3 diff --git a/integration_tests/test_c_interop_04.py b/integration_tests/test_c_interop_04.py index 483e4266c8..0be53d4841 100644 --- a/integration_tests/test_c_interop_04.py +++ b/integration_tests/test_c_interop_04.py @@ -1,10 +1,10 @@ -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 -@ccall -def sum_pi32_i32(x: CPtr) -> i32: - pass +# @ccall +# def sum_pi32_i32(x: CPtr) -> i32: +# pass def test_c_callbacks(): xi32: i32[4] @@ -19,8 +19,8 @@ def test_c_callbacks(): p = empty_c_void_p() p_c_pointer(pointer(xi32), p) print(pointer(xi32), p) - sumi32 = sum_pi32_i32(p) - print(sumi32) - assert sumi32 == 18 + # sumi32 = sum_pi32_i32(p) + # print(sumi32) + # assert sumi32 == 18 test_c_callbacks() 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 bfc52328b5..dd91b1f911 100644 --- a/integration_tests/test_cmath.py +++ b/integration_tests/test_cmath.py @@ -1,6 +1,7 @@ from cmath import (exp, log, sqrt, acos, asin, atan, cos, sin, tan, - acosh, asinh, atanh, cosh, sinh, tanh) -from ltypes import c64 + acosh, asinh, atanh, cosh, sinh, tanh, + phase, polar, rect) +from lpython import c64, c32, f64 def test_power_logarithmic(): x: c64 @@ -11,7 +12,7 @@ def test_power_logarithmic(): y = sqrt(x) a: c32 b: c32 - a = complex(3, 3) + a = c32(complex(3, 3)) b = exp(a) b = log(a) b = sqrt(a) @@ -29,7 +30,7 @@ def test_trigonometric(): y = tan(x) a: c32 b: c32 - a = complex(3, 3) + a = c32(complex(3, 3)) b = acos(a) b = asin(a) b = atan(a) @@ -50,7 +51,7 @@ def test_hyperbolic(): y = tanh(x) a: c32 b: c32 - a = complex(3, 3) + a = c32(complex(3, 3)) b = acosh(a) b = asinh(a) b = atanh(a) @@ -59,6 +60,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() \ No newline at end of file diff --git a/integration_tests/test_complex.py b/integration_tests/test_complex.py deleted file mode 100644 index 5c4984abd9..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 = 2 + 3j - a: f64 - b: f64 - eps: f64 - eps = 1e-12 - a = x.real - b = x.imag - assert abs(a - 2) < eps - assert abs(b - 3) < 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 = -423.5430806348152437 - a3: f32 - a3 = 34.5 - x2: c32 - x2 = complex(a2, a3) # (f32, f32) - - assert abs(x2.imag - 34.5) < eps - - i1: i32 - i1 = -5 - i2: i64 - i2 = -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 = complex(3, 4) - eps: f64 - eps = 1e-12 - assert abs(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 = 2 + 3j - y = 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 = 2 + 3j - y = 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 = complex(3, 4.5) - _c: c32 - _c = -c - assert abs(_c.real - (-3.0)) < 1e-12 - assert abs(_c.imag - (-4.5)) < 1e-12 - _c = complex(5, -78) - _c = -_c - assert abs(_c.real - (-5.0)) < 1e-12 - assert abs(_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 = 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 = 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 8ee0734873..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} @@ -7,25 +7,25 @@ def test_dict(): size1: i32 for i in range(1000, 1000 + size, 7): - rollnumber2cpi[i] = float(i/100.0 + 5.0) + rollnumber2cpi[i] = f64(i)/100.0 + 5.0 - size1 = size/7 + 1 + size1 = i32(size/7 + 1.0) for i in range(1000, 1000 + size//2, 7): - assert abs(rollnumber2cpi.pop(i) - i/100.0 - 5.0) <= 1e-12 + assert abs(rollnumber2cpi.pop(i) - f64(i)/100.0 - 5.0) <= 1e-12 size1 = size1 - 1 assert len(rollnumber2cpi) == size1 for i in range(1000, 1000 + size//2, 7): - rollnumber2cpi[i] = - i/100.0 - 5.0 + rollnumber2cpi[i] = - f64(i)/100.0 - 5.0 for i in range(1000, 1000 + size//2, 7): - assert abs(rollnumber2cpi[i] + i/100.0 + 5.0) <= 1e-12 + assert abs(rollnumber2cpi[i] + f64(i)/100.0 + 5.0) <= 1e-12 for i in range(1000, 1000 + size, 7): - rollnumber2cpi[i] = - i/100.0 - 5.0 + rollnumber2cpi[i] = - f64(i)/100.0 - 5.0 for i in range(1000, 1000 + size, 7): - 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 diff --git a/integration_tests/test_dict_03.py b/integration_tests/test_dict_03.py index 254ac25d97..24583d4ba8 100644 --- a/integration_tests/test_dict_03.py +++ b/integration_tests/test_dict_03.py @@ -1,12 +1,12 @@ -from ltypes import f64, i32, i64 +from lpython import f64, i32, i64 def power2(i: i64, mod: i64) -> i64: - if i == 0 or i == 1: - return 2**i + if i == i64(0) or i == i64(1): + return i64(2)**i p1: i64; p2: i64; px: i64; py: i64; - p1 = i//2 + p1 = i//i64(2) p2 = i - p1 px = power2(p1, mod) % mod py = power2(p2, mod) % mod @@ -18,7 +18,7 @@ def generate_key(i: i32) -> str: 8: 'i', 9: 'j'} mod: i32 = 99997 key_digits: i32 - key_digits = power2(int(i), int(mod)) + key_digits = i32(power2(int(i), int(mod))) key: str = "" while key_digits > 0: diff --git a/integration_tests/test_dict_04.py b/integration_tests/test_dict_04.py index 858eebb9cb..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(): @@ -13,7 +13,7 @@ def test_dict(): coords: tuple[f64, f64] eps: f64 = 1e-12 - n = 0 + n = i64(0) for i in range(1000, 1000 + size, 7): terms2poly[(i, i*i)] = int(i + i*i) @@ -23,8 +23,8 @@ def test_dict(): n += int(1) - size1 = size/7 - n = 0 + size1 = i32(size/7) + n = i64(0) for i in range(1000, 1000 + size//2, 7): assert terms2poly.pop((i, i*i)) == int(i + i*i) @@ -38,7 +38,7 @@ def test_dict(): assert len(terms2poly) == size1 n += int(1) - n = 0 + n = i64(0) for i in range(1000, 1000 + size//2, 7): terms2poly[(i, i*i)] = int(1 + 2*i + i*i) @@ -48,9 +48,9 @@ def test_dict(): n += int(1) - n = 0 + n = i64(0) for i in range(1000, 1000 + size//2, 7): - assert terms2poly[(i, i*i)] == (i + 1)*(i + 1) + assert terms2poly[(i, i*i)] == i64((i + 1)*(i + 1)) theta = float(n) * pi r = float(i) @@ -59,7 +59,7 @@ def test_dict(): n += int(1) - n = 0 + n = i64(0) for i in range(1000, 1000 + size, 7): terms2poly[(i, i*i)] = int(1 + 2*i + i*i) @@ -68,13 +68,13 @@ def test_dict(): rtheta2coords[(int(i), n)] = (r * cos(theta), r * sin(theta)) n += int(1) - n = 0 + n = i64(0) for i in range(1000, 1000 + size, 7): - assert terms2poly[(i, i*i)] == (i + 1)*(i + 1) + assert terms2poly[(i, i*i)] == i64((i + 1)*(i + 1)) theta = float(n) * pi r = float(i) - assert abs(r**2 - rtheta2coords[(int(i), n)][0]**2 - r**2 * sin(theta)**2) <= eps + assert abs(r**2.0 - rtheta2coords[(int(i), n)][0]**2.0 - r**2.0 * sin(theta)**2.0) <= eps n += int(1) test_dict() diff --git a/integration_tests/test_dict_05.py b/integration_tests/test_dict_05.py new file mode 100644 index 0000000000..df35e97494 --- /dev/null +++ b/integration_tests/test_dict_05.py @@ -0,0 +1,17 @@ +from lpython import i32, f64 + +def test_dict(): + rollnumber2cpi: dict[i32, f64] = {} + i: i32 + start: i32 = -500 + end: i32 = 501 + + for i in range(start, end): + 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 + + # assert len(rollnumber2cpi) == end - start + 1 + +test_dict() 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 new file mode 100644 index 0000000000..3f66e992c4 --- /dev/null +++ b/integration_tests/test_for_loop.py @@ -0,0 +1,39 @@ +from lpython import i32 + +def test_issue_1153(): + start: list[i32] = [-10, 0, 10] + stop: list[i32] = [20, 0, -20] + a: i32; b: i32; c: i32; count: i32; j: i32 + + for a in range(len(start)): + for b in range(len(stop)): + count = 0 + for j in range(start[a], stop[b], -2): + count += 1 + assert count == max(0, (start[a] - stop[b]) // 2) + + for a in range(len(start)): + for b in range(len(stop)): + count = 0 + for j in range(start[a], stop[b], -1): + count += 1 + assert count == max(0, start[a] - stop[b]) + + + for a in range(len(start)): + for b in range(len(stop)): + count = 0 + for j in range(start[a], stop[b], 2): + count += 1 + assert count == max(0, (stop[b] - start[a]) // 2) + + for a in range(len(start)): + for b in range(len(stop)): + count = 0 + for j in range(start[a], stop[b], 1): + count += 1 + assert count == max(0, stop[b] - start[a]) + + + +test_issue_1153() diff --git a/integration_tests/test_generics_01.py b/integration_tests/test_generics_01.py index 032f30c8e6..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 @@ -37,7 +37,7 @@ def add(a: i32, b: i32): @overload def add(a: i32, b: i64): - print(a + b) + print(i64(a) + b) def check(): @@ -60,7 +60,7 @@ def check(): add(1, 2) add(3) i: i64 - i = 10 + i = i64(10) add(2, i) check() diff --git a/integration_tests/test_global_decl.py b/integration_tests/test_global_decl.py new file mode 100644 index 0000000000..d256f37d15 --- /dev/null +++ b/integration_tests/test_global_decl.py @@ -0,0 +1,17 @@ +from lpython import i32, Const +from numpy import empty, int32 + +# issue-1368 + +SIZE: Const[i32] = i32(3) + +def main() -> None: + xs: i32[SIZE] = empty(SIZE, dtype=int32) + i: i32 + for i in range(SIZE): + xs[i] = i+1 + + for i in range(SIZE): + assert xs[i] == i+1 + +main() 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 dace251971..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 = 1.0 if 1.0 <= 0.0 else 0.0 - assert j == 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/__init__.py b/integration_tests/test_import/__init__.py new file mode 100644 index 0000000000..38b264b931 --- /dev/null +++ b/integration_tests/test_import/__init__.py @@ -0,0 +1,2 @@ +from .test_import_1 import print_a, print_b +from .test_import_2 import print_c diff --git a/integration_tests/test_import/import_module_01/__init__.py b/integration_tests/test_import/import_module_01/__init__.py new file mode 100644 index 0000000000..a876f383e8 --- /dev/null +++ b/integration_tests/test_import/import_module_01/__init__.py @@ -0,0 +1 @@ +from .test_import_4 import e, multiply 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 new file mode 100644 index 0000000000..f85a664a12 --- /dev/null +++ b/integration_tests/test_import/import_module_01/test_import_4.py @@ -0,0 +1,6 @@ +from lpython import i32, f64, Const + +e: Const[f64] = 2.71828182845904523536 + +def multiply(x: i32, y: i32) -> i32: + return x * y diff --git a/integration_tests/test_import/import_module_02/__init__.py b/integration_tests/test_import/import_module_02/__init__.py new file mode 100644 index 0000000000..bd92f73f15 --- /dev/null +++ b/integration_tests/test_import/import_module_02/__init__.py @@ -0,0 +1 @@ +from .test_import_3 import μ, add 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 new file mode 100644 index 0000000000..015ac2ae3f --- /dev/null +++ b/integration_tests/test_import/import_module_02/test_import_3.py @@ -0,0 +1,6 @@ +from lpython import i32, f64, Const + +μ: Const[f64] = 1.45136923488338105028 + +def add(x: i32, y: i32) -> i32: + return x + y 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/test_import_1.py b/integration_tests/test_import/test_import_1.py new file mode 100644 index 0000000000..347788a1ca --- /dev/null +++ b/integration_tests/test_import/test_import_1.py @@ -0,0 +1,5 @@ +def print_a() -> str: + return "A" + +def print_b() -> str: + return "B" diff --git a/integration_tests/test_import/test_import_2.py b/integration_tests/test_import/test_import_2.py new file mode 100644 index 0000000000..2c1064f112 --- /dev/null +++ b/integration_tests/test_import/test_import_2.py @@ -0,0 +1,2 @@ +def print_c() -> str: + return "C" diff --git a/integration_tests/test_import_01.py b/integration_tests/test_import_01.py new file mode 100644 index 0000000000..21750fdd80 --- /dev/null +++ b/integration_tests/test_import_01.py @@ -0,0 +1,5 @@ +import test_import + +print(test_import.print_a()) +print(test_import.print_b()) +print(test_import.print_c()) diff --git a/integration_tests/test_import_02.py b/integration_tests/test_import_02.py new file mode 100644 index 0000000000..5accbef42d --- /dev/null +++ b/integration_tests/test_import_02.py @@ -0,0 +1,13 @@ +from test_import.import_module_01 import multiply, e +from test_import.import_module_02 import add, μ + + +def f(): + print(e) + print(μ) + print(add(10, 20)) + print(multiply(10, 20)) + assert add(10, 20) == 30 + assert multiply(10, 20) == 200 + +f() diff --git a/integration_tests/test_import_03.py b/integration_tests/test_import_03.py new file mode 100644 index 0000000000..f37e890d74 --- /dev/null +++ b/integration_tests/test_import_03.py @@ -0,0 +1,7 @@ +from test_import import print_a +from test_import.test_import_1 import print_b +from test_import.import_module_01.test_import_4 import e + +print(print_a()) +print(print_b()) +print(e) diff --git a/integration_tests/test_import_04.py b/integration_tests/test_import_04.py new file mode 100644 index 0000000000..aa0da3bcf6 --- /dev/null +++ b/integration_tests/test_import_04.py @@ -0,0 +1,8 @@ +import test_modules + +def main0(): + print(test_modules.sinx(0.5)) + print(test_modules.cosx(0.5)) + assert abs(test_modules.sinx(0.5) + test_modules.cosx(0.5) - 1.0) <= 1e-12 + +main0() 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_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 9fea6d3f71..755719a27b 100644 --- a/integration_tests/test_issue_518.py +++ b/integration_tests/test_issue_518.py @@ -1,21 +1,21 @@ -from ltypes import i64 +from lpython import i64 def fib(n: i64) -> i64: - if n < 2: + if n < i64(2): return n else: - return fib(n - 1) + fib(n - 2) + return fib(n - i64(1)) + fib(n - i64(2)) def main0(): ans: i64 - ans = fib(15) - assert ans == 610 + ans = fib(i64(15)) + assert ans == i64(610) def main(): # test of issue-529 ans: i64 - ans = fib(10) - assert ans == 55 + ans = fib(i64(10)) + assert ans == i64(55) main0() diff --git a/integration_tests/test_list_01.py b/integration_tests/test_list_01.py index d6cd9bff0c..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] @@ -19,13 +19,13 @@ def test_list_01(): f.append(float(i + 6)) for i in range(15): - assert (f[i] - a[i]) == 1.0 + assert (f[i] - f64(a[i])) == 1.0 for i in range(15): - f[i] = f[i] + i + f[i] = f[i] + f64(i) for i in range(15): - assert (f[i] - a[i]) == (i + 1.0) + assert (f[i] - f64(a[i])) == (f64(i) + 1.0) def test_list_02(): x: list[i32] = [1, 2] @@ -42,8 +42,42 @@ def test_list_02(): for j in range(len(y)): assert x[j] == y[j] +# Negative Indexing +def test_list_03(): + x: list[f64] = [] + + i: i32 + for i in range(2): + x.append(float(i)) + + assert x[1] == x[-1] + assert x[0] == x[-2] + assert x[-1] == 1.0 + assert x[-2] == 0.0 + + size: i32 = 2 + for i in range(100): + x.append((i * size)/2) + size = len(x) + + 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 2beca3b6d1..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"] @@ -27,7 +27,7 @@ def test_list_01(): a[10] = string for i in range(12): - if int(i / 2) == 2 * i: + if i32(i / 2) == 2 * i: b[i] = str(i) + "_str" else: string = str(i) + "_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 f0bd346bc8..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 +from lpython import i32, f64 def test_list_01(): x: list[i32] = [] @@ -12,7 +12,7 @@ def test_list_01(): x.insert(len(x), j) for i in x: - j = int(sqrt(i - 10.0)) + j = i32(sqrt(f64(i - 10))) y.append(j) for i in range(len(x)): diff --git a/integration_tests/test_list_05.py b/integration_tests/test_list_05.py index 33ff73fec4..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] @@ -57,7 +57,7 @@ def test_list_of_tuples(): t = l1[len(l1) - 1] assert t[0] == size//2 - 1 - assert t[1] == size//2 - 1 + assert t[1] == f64(size//2 - 1) assert t[2] == str(size//2 - 1) + "_str" l1 = insert_tuples_into_list(l1, size) diff --git a/integration_tests/test_list_06.py b/integration_tests/test_list_06.py index 9081430c89..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]): @@ -12,11 +12,11 @@ def check_mat_and_vec(mat: list[list[f64]], vec: list[f64]): assert mat[i][j] == float(i + j) for i in range(cols): - assert vec[i] == 2 * float(i) + 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 @@ -33,12 +33,12 @@ def test_list_of_lists(): vec.clear() for i in range(cols): - vec.append(2 * float(i)) + vec.append(2.0 * float(i)) 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] == 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] == 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 a3c46da91b..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 @@ -46,9 +46,9 @@ def test_tuple_with_lists(): for i in range(rows): for j in range(cols): - assert mat[i][j] - vec[j] == i - j + 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] == -(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] == -(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 b810e81a75..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)): @@ -27,11 +27,11 @@ def sort_list(): assert len(x) == size def l1norm(v: list[i32]) -> f64: - result: f64 = 0 + result: f64 = 0.0 i: i32 for i in range(len(v)): - result = result + v[i] + result = result + f64(v[i]) return result diff --git a/integration_tests/test_list_09.py b/integration_tests/test_list_09.py new file mode 100644 index 0000000000..650293e474 --- /dev/null +++ b/integration_tests/test_list_09.py @@ -0,0 +1,48 @@ +from lpython import i32 + +def test_list_concat(): + x: list[i32] = [] + y: list[i32] = [] + z: list[i32] = x + y + i: i32 + assert len(z) == 0 + + x = [1, 2, 3] + z = x + y + for i in range(1, 4): + 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 + + x = [1, 2, 3, 4, 5] + z = x + y + for i in range(1, 9): + assert z[i-1] == i + + 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 + y.clear() + for i in range(1, 100): + assert z[i-1] == i + + c: list[str] + d: list[str] + 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 + + +test_list_concat() diff --git a/integration_tests/test_list_10.py b/integration_tests/test_list_10.py new file mode 100644 index 0000000000..5216054ddf --- /dev/null +++ b/integration_tests/test_list_10.py @@ -0,0 +1,52 @@ +from lpython import i32 + +def test_list_section(): + x: list[i32] = [] + y: list[i32] + y = x[:] + assert len(y) == 0 + y = x[0:0] + assert len(y) == 0 + + x = [1, 2, 3] + y = x[0:10] + assert len(x) == len(y) + x.clear() + + i: i32 + for i in range(50): + x.append(i) + + y = x[15:35] + j: i32 = 0 + for i in range(15, 35): + assert x[i] == y[j] + j += 1 + + y = x[:50] + for i in range(50): + assert i == y[i] + + y = x[10:] + j = 0 + for i in range(10, 50): + assert x[i] == y[j] + j += 1 + + y = x[::2] + j = 0 + for i in range(0, len(x), 2): + assert x[i] == y[j] + j += 1 + + c: list[str] + c = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] + d: list[str] + d = c[3:6] + assert d[0] == 'd' + assert d[1] == 'e' + assert d[2] == 'f' + assert len(d) == 3 + + +test_list_section() 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 new file mode 100644 index 0000000000..639e639a55 --- /dev/null +++ b/integration_tests/test_list_section.py @@ -0,0 +1,33 @@ +from lpython import i32 + + +def test_issue_1369(): + s: list[str] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] + start: i32 + end: i32 + step: i32 + start = 1 + end = 4 + step = 1 + empty_list: list[str] = [] + + # Check all possible combinations + assert s[::] == ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] + assert s[1:4:] == ['b', 'c', 'd'] + assert s[:4:5] == ['a'] + assert s[::-1] == ['k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'] + assert s[3:12:3] == ['d', 'g', 'j'] + assert s[1::3] == ['b', 'e', 'h', 'k'] + assert s[4::] == ['e', 'f', 'g', 'h', 'i', 'j', 'k'] + assert s[:5:] == ['a', 'b', 'c', 'd', 'e'] + assert s[3:9:3] == ['d', 'g'] + assert s[10:3:-2] == ['k', 'i', 'g', 'e'] + assert s[-2:-10] == empty_list + assert s[-3:-9:-3] == ['i', 'f'] + assert s[-3:-10:-3] == ['i', 'f', 'c'] + assert s[start:end:step] == ['b', 'c', 'd'] + assert s[start:2*end-3:step] == ['b', 'c', 'd', 'e'] + assert s[start:2*end-3:-step] == empty_list + + +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 c656872f22..b79d82f161 100644 --- a/integration_tests/test_math.py +++ b/integration_tests/test_math.py @@ -1,15 +1,16 @@ 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) -from ltypes import i32, i64, f32, f64 + modf, fsum, prod, dist, frexp, isclose) +import math +from lpython import i8, i16, i32, i64, f32, f64 eps: f64 eps = 1e-12 def test_factorial_1(): i: i64 - i = factorial(10) - assert i == 3628800 + i = factorial(i64(10)) + assert i == i64(3628800) def test_comb(): @@ -59,7 +60,6 @@ def test_exp(): i = exp(2.34) assert abs(i - 10.381236562731843) < eps - def test_pow(): eps: f64 eps = 1e-12 @@ -70,10 +70,10 @@ def test_pow(): assert abs(pow(x, y) - 43.14280115650323) < eps a: i64 - a = 2 + a = i64(2) b: i64 - b = 4 - assert pow(a, b) == 16 + b = i64(4) + assert pow(a, b) == i64(16) def test_ldexp(): i: f64 @@ -117,21 +117,21 @@ def test_lcm(): def test_floor(): i: i64 i = floor(10.02) - assert i == 10 - i = floor(-13) - assert i == -13 + assert i == i64(10) + i = floor(-i64(13)) + assert i == -i64(13) i = floor(-13.31) - assert i == -14 + assert i == -i64(14) def test_ceil(): i: i64 i = ceil(10.02) - assert i == 11 - i = ceil(-13) - assert i == -13 + assert i == i64(11) + i = ceil(-i64(13)) + assert i == -i64(13) i = ceil(-13.31) - assert i == -13 + assert i == -i64(13) def test_remainder(): @@ -155,13 +155,13 @@ def test_expm1(): def test_trunc(): i: i64 i = trunc(3.5) - assert i == 3 + assert i == i64(3) i = trunc(-4.5) - assert i == -4 + assert i == -i64(4) i = trunc(5.5) - assert i == 5 + assert i == i64(5) i = trunc(-4.5) - assert i == -4 + assert i == -i64(4) def test_fsum(): res: f64 @@ -172,15 +172,15 @@ def test_fsum(): res = fsum(arr_i32) assert abs(res - 18.0) < eps - a: i64 = 12 - b: i64 = 6 + a: i64 = i64(12) + b: i64 = i64(6) arr_i64: list[i64] arr_i64 = [a, b] res = fsum(arr_i64) assert abs(res - 18.0) < eps - x: f32 = 12.5 - y: f32 = 6.5 + x: f32 = f32(12.5) + y: f32 = f32(6.5) arr_f32: list[f32] arr_f32 = [x, y] res = fsum(arr_f32) @@ -200,15 +200,15 @@ def test_prod(): res = prod(arr_i32) assert abs(res - 72.0) < eps - a: i64 = 12 - b: i64 = 6 + a: i64 = i64(12) + b: i64 = i64(6) arr_i64: list[i64] arr_i64 = [a, b] res = prod(arr_i64) assert abs(res - 72.0) < eps - x: f32 = 12.5 - y: f32 = 6.5 + x: f32 = f32(12.5) + y: f32 = f32(6.5) arr_f32: list[f32] arr_f32 = [x, y] res = prod(arr_f32) @@ -219,6 +219,14 @@ def test_prod(): res = prod(arr_f64) assert abs(res - 80.64) < eps +def test_dist(): + x: list[f64] + y: list[f64] + eps: f64 = 1e-12 + x = [1.0, 2.2, 3.333, 4.0, 5.0] + y = [6.1, 7.2, 8.0, 9.0, 10.0] + assert abs(dist(x, y) - 11.081105044173166) < eps + def test_modf(): i: f64 i = 3.14 @@ -234,6 +242,69 @@ def test_modf(): assert abs(res[1] + 442.0) <= 1e-6 +def test_issue_1242(): + assert abs(math.pi - 3.14159265358979323846) < 1e-10 + assert abs(math.e - 2.7182818284590452353) < 1e-10 + + # https://github.com/lcompilers/lpython/pull/1243#discussion_r1008810444 + pi: f64 = 8.4603959020429502 + assert abs(pi - 8.4603959020429502) < 1e-10 + assert abs(math.pi - 3.14159265358979323846) < 1e-10 + 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() @@ -256,7 +327,11 @@ def check(): test_trunc() test_fsum() test_prod() + 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 ecece07d69..41c4441660 100644 --- a/integration_tests/test_math1.py +++ b/integration_tests/test_math1.py @@ -1,10 +1,13 @@ import math -from ltypes import i32 +from math import pi, e +from lpython import i32 def f(): i: i32 i = math.factorial(3) assert i == 6 + assert abs(pi - 3.14159265358979323846) < 1e-10 + assert abs(e - 2.7182818284590452353) < 1e-10 f() diff --git a/integration_tests/test_math_02.py b/integration_tests/test_math_02.py index 5dc5d4f618..a15b604326 100644 --- a/integration_tests/test_math_02.py +++ b/integration_tests/test_math_02.py @@ -1,38 +1,39 @@ 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 lpython import f64 def test_trig(): eps: f64 = 1e-12 - assert abs(sin(0.0)-0) < eps - assert abs(sin(pi/2)-1) < eps - assert abs(cos(0.0)-1) < eps - assert abs(cos(pi/2)-0) < eps - assert abs(tan(0.0)-0) < eps - assert abs(tan(pi/4)-1) < eps - assert abs(asin(1.0) - pi/2) < eps - assert abs(acos(1.0) - 0) < eps - assert abs(atan(1.0) - pi/4) < eps - assert abs(atan2(1.0, 1.0) - pi/4) < eps + assert abs(sin(0.0) - 0.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.0) < eps + assert abs(tan(0.0) - 0.0) < 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.0) < eps + assert abs(atan2(1.0, 1.0) - pi/4.0) < eps def test_sqrt(): eps: f64 = 1e-12 assert abs(sqrt(2.0) - 1.4142135623730951) < eps - assert abs(sqrt(9.0) - 3) < eps + assert abs(sqrt(9.0) - 3.0) < eps def test_log(): eps: f64 = 1e-12 - assert abs(log(1.0) - 0) < eps - assert abs(log(2.718281828459) - 1) < eps - assert abs(log2(2.0) - 1) < eps - assert abs(log10(10.0) - 1) < eps + assert abs(log(1.0) - 0.0) < eps + assert abs(log(2.718281828459) - 1.0) < eps + assert abs(log2(2.0) - 1.0) < eps + assert abs(log10(10.0) - 1.0) < eps def test_special(): eps: f64 = 1e-12 assert abs(erf(2.0) - 0.9953222650189527) < eps assert abs(erfc(2.0) - 0.0046777349810472645) < eps - assert abs(erf(2.0) + erfc(2.0) - 1) < eps - assert abs(gamma(5.0) - 24) < eps + assert abs(erf(2.0) + erfc(2.0) - 1.0) < eps + assert abs(gamma(5.0) - 24.0) < eps assert abs(lgamma(5.0) - log(gamma(5.0))) < eps def test_hyperbolic(): 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/integration_tests/test_modules/__init__.py b/integration_tests/test_modules/__init__.py new file mode 100644 index 0000000000..f0fc335422 --- /dev/null +++ b/integration_tests/test_modules/__init__.py @@ -0,0 +1 @@ +from .mathfn import sinx, cosx diff --git a/integration_tests/test_modules/mathfn/__init__.py b/integration_tests/test_modules/mathfn/__init__.py new file mode 100644 index 0000000000..565ce86fb4 --- /dev/null +++ b/integration_tests/test_modules/mathfn/__init__.py @@ -0,0 +1 @@ +from .sin import sinx, cosx diff --git a/integration_tests/test_modules/mathfn/sin.py b/integration_tests/test_modules/mathfn/sin.py new file mode 100644 index 0000000000..4d26103b13 --- /dev/null +++ b/integration_tests/test_modules/mathfn/sin.py @@ -0,0 +1,7 @@ +from lpython import f64 + +def sinx(x: f64) -> f64: + return x + 1.0 + +def cosx(x: f64) -> f64: + return x - 1.0 diff --git a/integration_tests/test_numpy_01.py b/integration_tests/test_numpy_01.py index 60877c092b..85685d01df 100644 --- a/integration_tests/test_numpy_01.py +++ b/integration_tests/test_numpy_01.py @@ -1,14 +1,14 @@ # This test handles various aspects of local arrays using the `numpy.empty()` # function -from ltypes import f64 -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] = i+0.5 + a[i] = f64(i) + 0.5 eps: f64 eps = 1e-12 assert abs(a[0] - 0.5) < eps @@ -18,10 +18,10 @@ 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 * i + a[i] = 1.0 * f64(i) return a def test_return_arrays(): @@ -29,10 +29,10 @@ def test_return_arrays(): a = f() eps: f64 eps = 1e-12 - assert abs(a[0] - 0) < eps - assert abs(a[1] - 1) < eps - assert abs(a[2] - 2) < eps - assert abs(a[3] - 3) < eps + assert abs(a[0] - 0.0) < eps + assert abs(a[1] - 1.0) < eps + assert abs(a[2] - 2.0) < eps + assert abs(a[3] - 3.0) < eps def check(): test_local_arrays() diff --git a/integration_tests/test_numpy_02.py b/integration_tests/test_numpy_02.py index ce5940f99c..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 @@ -36,7 +35,7 @@ def arange(n: i32) -> i64[n]: A = empty(n, dtype=int64) i: i32 for i in range(n): - A[i] = i + A[i] = i64(i) return A #: sqrt() as a generic procedure. @@ -44,16 +43,16 @@ def arange(n: i32) -> i64[n]: #: i32, i64, f32, f64, bool @overload def sqrt(n: i32) -> f64: - return n**(1/2) + return f64(n)**(1/2) @overload def sqrt(n: i64) -> f64: - return n**(1/2) + return f64(n)**(1/2) @overload def sqrt(f: f32) -> f32: half: f32 - half = 1/2 + half = f32(1/2) return f**half @overload @@ -72,16 +71,16 @@ def sqrt(b: bool) -> f64: #: i32, i64, f32, f64, bool @overload def exp(n: i32) -> f64: - return e**n + return e**f64(n) @overload def exp(n: i64) -> f64: - return e**n + return e**f64(n) @overload def exp(f: f32) -> f32: ef32: f32 - ef32 = e + ef32 = f32(e) return ef32**f @overload @@ -101,18 +100,18 @@ def exp(b: bool) -> f64: @overload def fabs(n: i32) -> f64: if n < 0: - return -1.0*n - return 1.0*n + return -f64(n) + return f64(n) @overload def fabs(n: i64) -> f64: - if n < 0: - return -1.0*n - return 1.0*n + if n < i64(0): + return -f64(n) + return f64(n) @overload def fabs(f: f32) -> f32: - if f < 0.0: + if f < f32(0.0): return -f return f @@ -126,14 +125,13 @@ 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)*i/(num-1) + A[i] = start + (stop-start)*f64(i)/f64(num-1) return A #------------------------------ @@ -149,19 +147,19 @@ def sign(x: i32) -> i32: @overload def sign(x: i64) -> i64: result: i64 - if x == 0: - result = 0 - elif x > 0: - result = 1 + if x == i64(0): + result = i64(0) + elif x > i64(0): + result = i64(1) else: - result = -1 + result = -i64(1) return result @overload def sign(x: f32) -> f32: fabsf32: f32 fabsf32 = fabs(x) - return x/fabsf32 + return f32(x/fabsf32) @overload def sign(x: f64) -> f64: @@ -202,7 +200,7 @@ def real(b: bool) -> i32: #------------------------------ @overload def imag(c: c32) -> f32: - return c.imag + return f32(c.imag) @overload def imag(c: c64) -> f64: @@ -214,15 +212,11 @@ def imag(x: i32) -> i32: @overload def imag(x: i64) -> i64: - result: i64 - result = 0 - return result + return i64(0) @overload def imag(f: f32) -> f32: - result: f32 - result = 0.0 - return result + return f32(0.0) @overload def imag(f: f64) -> f64: @@ -252,10 +246,10 @@ def test_ones(): def test_arange(): a: i64[4] a = arange(4) - assert a[0] == 0 - assert a[1] == 1 - assert a[2] == 2 - assert a[3] == 3 + assert a[0] == i64(0) + assert a[1] == i64(1) + assert a[2] == i64(2) + assert a[3] == i64(3) def test_sqrt(): a: f64 @@ -267,13 +261,13 @@ def test_sqrt(): assert abs(sqrt(False) - 0.0) < eps i: i64 - i = 4 + i = i64(4) a = sqrt(i) - assert abs(a - 2.0) < eps + assert abs(f64(a) - 2.0) < eps f: f32 - f = 4.0 - assert abs(sqrt(f) - 2.0) < eps + f = f32(4.0) + assert abs(f64(sqrt(f)) - 2.0) < eps def test_exp(): a: f64 @@ -286,12 +280,12 @@ def test_exp(): assert abs(exp(True) - 2.719) < eps i: i64 - i = 4 + i = i64(4) a = exp(i) assert abs(a - 54.598150033144236) < eps f: f32 - f = -4.0 + f = -f32(4.0) print(exp(f)) def test_fabs(): @@ -304,13 +298,13 @@ def test_fabs(): assert abs(fabs(True) - 1.0) < eps i: i64 - i = -4 + i = -i64(4) a = fabs(i) assert abs(a - 4.0) < eps f: f32 - f = -4.0 - assert abs(fabs(f) - 4.0) < eps + f = -f32(4.0) + assert abs(f64(fabs(f)) - 4.0) < eps def test_linspace(): a: f64[4] @@ -327,14 +321,14 @@ def test_sign(): assert sign(0) == 0 f: f32 - f = -3.0 - assert sign(f) == -1.0 - f = 235.4142135623730951 - assert sign(f) == 1.0 + f = -f32(3.0) + assert sign(f) == -f32(1.0) + f = f32(235.4142135623730951) + assert sign(f) == f32(1.0) a2: i64 - a2 = sign(3) - assert a2 == 1 + a2 = sign(i64(3)) + assert a2 == i64(1) f2: f64 f2 = -3.0 @@ -342,8 +336,8 @@ def test_sign(): def test_real(): c: c32 - c = 4 + 3j - assert abs(real(c) - 4.0) < eps + c = c32(4) + c32(3j) + assert abs(f64(real(c)) - 4.0) < eps c2: c64 c2 = complex(5, -6) @@ -354,8 +348,8 @@ def test_real(): assert real(i) == 4 i2: i64 - i2 = -4 - assert real(i2) == -4 + i2 = -i64(4) + assert real(i2) == -i64(4) f: f64 f = 534.6475 @@ -364,20 +358,20 @@ def test_real(): def test_imag(): c: c32 - c = 4 + 3j - assert abs(imag(c) - 3.0) < eps + c = c32(4) + c32(3j) + assert abs(f64(imag(c)) - 3.0) < eps c2: c64 c2 = complex(5, -6) - assert abs(imag(c2) - -6.0) < eps + assert abs(f64(imag(c2)) - -6.0) < eps i: i32 i = 4 assert imag(i) == 0 i2: i64 - i2 = -4 - assert imag(i2) == 0 + i2 = -i64(4) + assert imag(i2) == i64(0) f: f64 f = 534.6475 diff --git a/integration_tests/test_numpy_03.py b/integration_tests/test_numpy_03.py index 1ed3cf4caf..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,31 +9,31 @@ 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): i = k//16 j = k - i*16 - assert abs(b[k] - i - j - 0.5) <= eps + 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] = i + j + k + 0.5 + 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 = int(l/256) + i = i32(l/256) j = (l - i*256)//16 k = (l - i*256 - j*16) - assert abs(d[l] - i - j - k - 0.5) <= eps + assert abs(d[l] - f64(i + j + k) - 0.5) <= eps def test_1d_to_nd(d: f64[:]): i: i32 @@ -43,25 +43,25 @@ 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] = i + j + 0.5 + 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) for i in range(16): for j in range(16): - assert abs(a[i, j] - i - j - 0.5) <= eps + 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 @@ -69,7 +69,7 @@ def test_1d_to_nd(d: f64[:]): for i in range(16): for j in range(16): for k in range(16): - assert abs(c[i, j, k] - i - j - k - 0.5) <= eps + assert abs(c[i, j, k] - f64(i + j + k) - 0.5) <= eps def test_reshape_with_argument(): i: i32 @@ -78,19 +78,19 @@ 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] = i + j + 0.5 + 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 = int(l/256) + i = i32(l/256) j = (l - i*256)//16 k = (l - i*256 - j*16) - d[l] = i + j + k + 0.5 + d[l] = f64(i + j + k) + 0.5 test_1d_to_nd(d) diff --git a/integration_tests/test_numpy_04.py b/integration_tests/test_numpy_04.py index b37e9c1b49..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(): @@ -11,9 +11,9 @@ def test_array_01(): def test_array_02(): x: i32[3] = array([1, 2, 3]) eps: f64 = 1e-16 - assert abs(x[0] - 1) < eps - assert abs(x[1] - 2) < eps - assert abs(x[2] - 3) < eps + assert f64(abs(x[0] - 1)) < eps + assert f64(abs(x[1] - 2)) < eps + assert f64(abs(x[2] - 3)) < eps def check(): test_array_01() diff --git a/integration_tests/test_os.py b/integration_tests/test_os.py index 2706e6ba88..20f92c342d 100644 --- a/integration_tests/test_os.py +++ b/integration_tests/test_os.py @@ -1,14 +1,14 @@ -from ltypes import i64 +from lpython import i64 from os import (open, read, close, O_RDONLY) def test(): - path: str + path: str path = "../test_os.py" fd: i64 n: i64 fd = open(path, O_RDONLY) - n = 100 + n = i64(100) print(read(fd, n)) - close(fd) + close(fd) 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 new file mode 100644 index 0000000000..f076366b83 --- /dev/null +++ b/integration_tests/test_pass_compare.py @@ -0,0 +1,61 @@ +from lpython import i32 + + +def f(): + a11: tuple[i32, i32] + b11: tuple[i32, i32] + a11 = (1, 2) + b11 = (1, 2) + assert a11 == b11 + c11: tuple[i32, i32] + c11 = (1, 3) + assert a11 != c11 and c11 != b11 + a: tuple[tuple[i32, i32], str, bool] + b: tuple[tuple[i32, i32], str, bool] + a = (a11, 'ok', True) + b = (b11, 'ok', True) + assert a == b + b = (b11, 'notok', True) + assert a != b + + +def g(): + a11: list[i32] + b11: list[i32] + a11 = [1, 2, 3, 4] + b11 = [1, 2, 3, 4] + assert a11 == b11 + a11.append(5) + assert a11 != b11 + c11: list[i32] = [] + assert a11 != c11 + + d11: list[str] = ['a', 'b', '^', '*'] + e11: list[str] = ['a', 'b', '^'] + assert d11 != e11 + e11.append('*') + assert d11 == e11 + + f11: list[tuple[i32, i32]] = [] + x: tuple[i32, i32] + i: i32 + for i in range(10): + x = (i, i+2) + f11.append(x) + + g11: list[tuple[i32, i32]] = [] + for i in range(9): + x = (i, i+2) + g11.append(x) + assert g11 != f11 + x = (9, 11) + g11.append(x) + assert g11 == f11 + + +def check(): + f() + g() + + +check() 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_len.py b/integration_tests/test_set_len.py new file mode 100644 index 0000000000..8e66064dd3 --- /dev/null +++ b/integration_tests/test_set_len.py @@ -0,0 +1,10 @@ +from lpython import i32 + +def test_set(): + s: set[i32] + s = {1, 2, 22, 2, -1, 1} + 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_01.py similarity index 60% rename from integration_tests/test_statistics.py rename to integration_tests/test_statistics_01.py index 7e8a9dc299..3eeddeed6a 100644 --- a/integration_tests/test_statistics.py +++ b/integration_tests/test_statistics_01.py @@ -1,6 +1,7 @@ from statistics import (mean, fmean, geometric_mean, harmonic_mean, variance, - stdev, pvariance, pstdev, correlation, covariance, linear_regression) -from ltypes import i32, f64, i64, f32 + stdev, pvariance, pstdev, mode) +from lpython import i32, f64, i64 + eps: f64 eps = 1e-12 @@ -23,7 +24,7 @@ def test_mean(): d = [1, 3, 11] l: f64 l = mean(d) - assert abs(l - 5) < eps + assert abs(l - 5.0) < eps def test_fmean(): a: list[i32] @@ -124,68 +125,35 @@ def test_pstdev(): k = pstdev(b) assert abs(k - 0.37537181567080935) < eps - -def test_covariance(): +def test_mode(): 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 + a = [3, 1, 12, 4, 0] + i: i32 + i = mode(a) + assert i == 3 - 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] + b = [4, 2, 4, 4, 2, 3, 5] + j: i32 + j = mode(b) + assert j == 4 - 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 + c: list[i32] + c = [2, 3, 4, 1, 2, 4, 5] + k: i32 + k = mode(c) + assert k == 2 - a: list[i32] - b: list[i32] - a = [12, 24, 2, 1, 43, 53, 23] - b = [2, 13, 14, 63, 49, 7, 3] + d: list[i32] + d = [-1, 2, -3, -5, -3, -1, 4, -2, 4, -5, -3, 4, -3] + k = mode(d) + assert k == -3 - slope, intercept = linear_regression(a, b) + 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) - assert abs(slope + 0.18514007308160782) < eps - assert abs(intercept - 25.750304506699152) < eps def check(): test_mean() @@ -196,8 +164,6 @@ def check(): test_stdev() test_pvariance() test_pstdev() - test_linear_regression() - test_correlation() - test_covariance() + 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..6be357aa3b 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,24 +39,175 @@ 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 check(): f() test_str_concat() test_str_index() test_str_slice() test_str_repeat() + 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 d9b140d9e2..5dd91d3d35 100644 --- a/integration_tests/test_str_03.py +++ b/integration_tests/test_str_03.py @@ -1,14 +1,36 @@ +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 = 1 - j: i16 = 2 + i: i8 = i8(1) + j: i16 = i16(2) k: i32 = 3 - l: i64 = 4 + l: i64 = i64(4) print("abc:", i, j, k, l) + +def test_issue_1124(): + a: str + a = "012345" + assert a[-1] == "5" + assert a[-1] == a[5] + assert a[-2] == a[4] + assert a[-4] == "2" + + 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 1f2160863d..b8b24cf8fa --- a/integration_tests/test_str_attributes.py +++ b/integration_tests/test_str_attributes.py @@ -1,19 +1,37 @@ 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(): s: str s = "AaaaAABBbbbbBB!@12223BN" assert s.lower() == "aaaaaabbbbbbbb!@12223bn" assert "DDd12Vv" .lower() == "ddd12vv" + assert "".lower() == "" + + +def upper(): + s: str + s = "AaaaAABBbbbbBB!@12223BN" + assert s.upper() == "AAAAAABBBBBBBB!@12223BN" + assert "DDd12Vv".upper() == "DDD12VV" + assert "".upper() == "" + def strip(): s: str @@ -24,12 +42,16 @@ def strip(): assert " AASAsaSas " .rstrip() == " AASAsaSas" assert " AASAsaSas " .lstrip() == "AASAsaSas " assert " AASAsaSas " .strip() == "AASAsaSas" + assert "".strip() == "" + def swapcase(): s: str s = "aaaaaabbbbbbbb!@12223bn" assert s.swapcase() == "AAAAAABBBBBBBB!@12223BN" assert "AASAsaSas" .swapcase() == "aasaSAsAS" + assert "".swapcase() == "" + def find(): s: str @@ -50,7 +72,32 @@ def find(): s2 = "" assert s2.find("") == 0 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 s = " empty" @@ -67,10 +114,411 @@ def startswith(): s = "" assert s.startswith("") == True assert s.startswith("sdd") == False + 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() + -capitalize() -lower() -strip() -swapcase() -find() -startswith() +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 6970d5a591..3c94dea4b9 100644 --- a/integration_tests/test_str_to_int.py +++ b/integration_tests/test_str_to_int.py @@ -1,23 +1,31 @@ -from ltypes import i32 +from lpython import i32 def f(): i: i32 - i = int("314") + i = i32(int("314")) assert i == 314 - i = int("-314") + i = i32(int("-314")) assert i == -314 s: str s = "123" - i = int(s) + i = i32(int(s)) assert i == 123 s = "-123" - i = int(s) + i = i32(int(s)) assert i == -123 s = " 1234" - i = int(s) + i = i32(int(s)) assert i == 1234 s = " -1234 " - i = int(s) + 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 f4ca66277e..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) @@ -18,7 +18,7 @@ def f(): bf: f64 (a, b) = t3 (af, bf) = t4 - assert af == a - assert bf == b + assert af == f64(a) + assert bf == f64(b) f() diff --git a/integration_tests/test_tuple_02.py b/integration_tests/test_tuple_02.py index 092ae84f00..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] @@ -21,9 +21,26 @@ def f(): t2 = set_tuple(i, j) t1 = merge_tuple(t1, t2) assert t1[0] == 55 - assert t1[1] == 55 + assert t1[1] == 55.0 assert t1[2] == "4510" assert t1[3] == complex(55, 55) print(t1[0], t1[1], t1[2], t1[3]) -f() + +def g_check(x: tuple[i32, i32], y: tuple[i32, i32]) -> bool: + return x[0] == y[0] + +def test_issue_1348(): + a11: tuple[i32, i32] + b11: tuple[i32, i32] + a11 = (1, 2) + b11 = (1, 2) + assert g_check(a11, b11) + + +def check(): + f() + test_issue_1348() + + +check() \ No newline at end of file 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 064f098e76..ee4c1e9169 100644 --- a/integration_tests/test_types_01.py +++ b/integration_tests/test_types_01.py @@ -1,14 +1,14 @@ -from ltypes import i8, i16, i32, i64 +from lpython import i8, i16, i32, i64 def test_i8(): i: i8 - i = 5 - assert i == 5 + i = i8(5) + assert i == i8(5) def test_i16(): i: i16 - i = 5 - assert i == 5 + i = i16(5) + assert i == i16(5) def test_i32(): i: i32 @@ -17,22 +17,22 @@ def test_i32(): def test_i64(): i: i64 - i = 5 - assert i == 5 + i = int(5) + assert i == i64(5) def test_i8_to_i64(): i1: i8 - i1 = -5 + i1 = -i8(5) i2: i64 - i2 = i1 - assert i2 == -5 + i2 = i64(i1) + assert i2 == -i64(5) def test_i64_to_i8(): i1: i64 - i1 = 6 + i1 = i64(6) i2: i8 - i2 = i1 - assert i2 == 6 + i2 = i8(i1) + assert i2 == i8(6) def check(): test_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_op_01.py similarity index 83% rename from integration_tests/test_unary_minus.py rename to integration_tests/test_unary_op_01.py index 02de00715f..08182832f1 100644 --- a/integration_tests/test_unary_minus.py +++ b/integration_tests/test_unary_op_01.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64 +from lpython import i32, f64 def f(): eps: f64 diff --git a/integration_tests/test_unary_plus.py b/integration_tests/test_unary_op_02.py similarity index 61% rename from integration_tests/test_unary_plus.py rename to integration_tests/test_unary_op_02.py index c8019dd260..396b8e07cc 100644 --- a/integration_tests/test_unary_plus.py +++ b/integration_tests/test_unary_op_02.py @@ -1,4 +1,4 @@ -from ltypes import i32, f64, c32 +from lpython import i32, f64, c32 def f(): eps: f64 @@ -13,10 +13,10 @@ def f(): assert abs(+f + 67.6457) < eps c: c32 - c = 4-5j + c = c32(4) - c32(5j) c = +c - assert abs(c.real - 4.000000) < eps - assert abs(c.imag - (-5.000000)) < eps + assert abs(f64(c.real) - 4.000000) < eps + assert abs(f64(c.imag) - (-5.000000)) < eps assert +True == 1 b: bool diff --git a/integration_tests/test_integer_bitnot.py b/integration_tests/test_unary_op_03.py similarity index 83% rename from integration_tests/test_integer_bitnot.py rename to integration_tests/test_unary_op_03.py index 2c12e8ecf4..48ba56fe5b 100644 --- a/integration_tests/test_integer_bitnot.py +++ b/integration_tests/test_unary_op_03.py @@ -1,4 +1,4 @@ -from ltypes import i32 +from lpython import i32 def f(): i: i32 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_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 new file mode 100644 index 0000000000..7fda2326df --- /dev/null +++ b/integration_tests/union_01.py @@ -0,0 +1,29 @@ +from lpython import Union, i32, i64, f64, f32, ccall, union + +@ccall +@union +class u_type(Union): + integer32: i32 + real32: f32 + real64: f64 + integer64: i64 + +def test_union(): + 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() diff --git a/integration_tests/union_02.py b/integration_tests/union_02.py new file mode 100644 index 0000000000..67cb4a3254 --- /dev/null +++ b/integration_tests/union_02.py @@ -0,0 +1,49 @@ +from lpython import i32, f64, i64, dataclass, ccall, union, Union + +@dataclass +class A: + ax: i32 + ay: f64 + +@dataclass +class B: + bx: i64 + by: f64 + +@dataclass +class C: + cx: i64 + cy: f64 + cz: f64 + +@ccall +@union +class D(Union): + 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() + + aobj: A = A(0, 1.0) + bobj: B = B(int(2), 7.0) + cobj: C = C(int(5), 13.0, 8.0) + + d.a = aobj + print(d.a.ax, d.a.ay) + assert d.a.ax == 0 + assert abs(d.a.ay - 1.0) <= 1e-12 + + d.b = bobj + print(d.b.bx, d.b.by) + assert d.b.bx == int(2) + assert abs(d.b.by - 7.0) <= 1e-12 + + d.c = cobj + print(d.c.cx, d.c.cy, d.c.cz) + assert d.c.cx == i64(5) + assert abs(d.c.cy - 13.0) <= 1e-12 + assert abs(d.c.cz - 8.0) <= 1e-12 + +test_struct_union() diff --git a/integration_tests/union_03.py b/integration_tests/union_03.py new file mode 100644 index 0000000000..4c8c538ac4 --- /dev/null +++ b/integration_tests/union_03.py @@ -0,0 +1,29 @@ +from lpython import Union, i32, i64, f64, f32, union + +# without ccall but same as union_01.py +@union +class u_type(Union): + integer32: i32 + real32: f32 + real64: f64 + integer64: i64 + +def test_union(): + 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() 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 new file mode 100644 index 0000000000..669470411c --- /dev/null +++ b/integration_tests/variable_decl_01.py @@ -0,0 +1,19 @@ +from lpython import i32, i64, Const +from numpy import empty, int64 + +def f(n: i32, m: i32): + 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): + for j in range(m): + for k in range(l): + a[i, j, k] = i64(i + j + k) + + for i in range(n): + for j in range(m): + for k in range(l): + print(a[i, j, k]) + assert a[i, j, k] == i64(i + j + k) + +f(5, 10) diff --git a/integration_tests/variable_decl_02.py b/integration_tests/variable_decl_02.py new file mode 100644 index 0000000000..9ee2a67034 --- /dev/null +++ b/integration_tests/variable_decl_02.py @@ -0,0 +1,14 @@ +from lpython import i32, i64 + +def f(): + d: i32 = 0 + c: i64 = i64(d + 1) + b: i64 = i64(d) + c + i64(2) + a: i32 = i32(b) + 20 + print(a, b, c, d) + assert d == 0 + assert c == i64(1) + assert b == i64(3) + assert a == 23 + +f() 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/run_tests.py b/run_tests.py index e09e5a420f..42fb5fb026 100755 --- a/run_tests.py +++ b/run_tests.py @@ -9,28 +9,43 @@ from compiler_tester.tester import color, fg, log, run_test, style, tester_main -def single_test(test, specific_test, verbose, no_llvm, update_reference): +def single_test(test, verbose, no_llvm, skip_run_with_dbg, skip_cpptranslate, update_reference, + verify_hash, no_color, specific_backends=None, excluded_backends=None): filename = test["filename"] - if specific_test and specific_test not in filename: - return + def is_included(backend): + return test.get(backend, False) \ + and (specific_backends is None or backend in specific_backends) \ + and (excluded_backends is None or backend not in excluded_backends) show_verbose = "" if not verbose else "-v" - tokens = test.get("tokens", False) - ast = test.get("ast", False) - ast_new = test.get("ast_new", False) - asr = test.get("asr", False) - llvm = test.get("llvm", False) - cpp = test.get("cpp", False) - c = test.get("c", False) - wat = test.get("wat", False) + tokens = is_included("tokens") + 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"] + "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_}") - log.debug(f"{color(style.bold)} START TEST: {color(style.reset)} {filename}") + if no_color: + log.debug(f" START TEST: {filename}") + else: + log.debug(f"{color(style.bold)} START TEST: {color(style.reset)} {filename}") extra_args = f"--no-error-banner {show_verbose}" @@ -41,7 +56,7 @@ def single_test(test, specific_test, verbose, no_llvm, update_reference): "lpython --no-color --show-tokens {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if ast: run_test( @@ -50,7 +65,7 @@ def single_test(test, specific_test, verbose, no_llvm, update_reference): "lpython --show-ast --no-color {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if ast_new: run_test( @@ -59,7 +74,7 @@ def single_test(test, specific_test, verbose, no_llvm, update_reference): "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) if asr: run_test( @@ -68,38 +83,81 @@ def single_test(test, specific_test, verbose, no_llvm, update_reference): "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 llvm: - if no_llvm: - log.info(f"{filename} * llvm SKIPPED as requested") - else: + if no_llvm: + log.info(f"{filename} * llvm SKIPPED as requested") + else: + if llvm: run_test( filename, "llvm", "lpython --no-color --show-llvm {infile} -o {outfile}", filename, update_reference, - extra_args) + extra_args=extra_args) + if llvm_dbg: + run_test( + filename, + "llvm_dbg", + "lpython --no-color --show-llvm -g --debug-with-line-column " + "{infile} -o {outfile}", + filename, + update_reference, + 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=extra_args) + if run_with_dbg: + if skip_run_with_dbg: + log.info(f"{filename} * run_with_dbg SKIPPED as requested") + else: + run_test( + filename, "run_dbg", + "lpython {infile} -g --debug-with-line-column --no-color", + 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/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