├── .clang-format ├── .github └── workflows │ └── CI.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build.sh ├── cmake ├── FindMACHO.cmake ├── Findclang.cmake └── UserOverride.cmake ├── environment_unix.yml ├── examples └── expr2.c ├── integration_tests ├── CMakeLists.txt ├── array_01.cpp ├── array_02.cpp ├── array_03.cpp ├── array_03_mdspan.cpp ├── array_04.cpp ├── array_04_mdspan.cpp ├── array_05.cpp ├── array_06.cpp ├── array_07.cpp ├── array_08.cpp ├── array_09.cpp ├── array_10.cpp ├── array_11.cpp ├── array_12.cpp ├── array_13.cpp ├── array_14.cpp ├── array_15.cpp ├── array_16.cpp ├── array_17.cpp ├── array_18.cpp ├── array_19.cpp ├── array_20.cpp ├── array_21.cpp ├── array_22.cpp ├── array_23.cpp ├── array_24.cpp ├── array_25.cpp ├── enum_01.cpp ├── enum_02.cpp ├── enum_03.cpp ├── enum_04.cpp ├── expr1.c ├── expr2.c ├── expr3.c ├── function_01.cpp ├── lnn │ ├── perceptron │ │ └── perceptron_main.hpp │ ├── regression │ │ └── regression_main.hpp │ └── utils │ │ └── utils_main.hpp ├── loop_01.cpp ├── lpdraw │ └── draw.hpp ├── nbody_01.cpp ├── nbody_02.cpp ├── pointer_01.cpp ├── pointer_02.cpp ├── pointer_03.cpp ├── pytorch_01.cpp ├── run_tests.py ├── struct_01.cpp ├── struct_02.cpp ├── struct_02_m_01.h ├── struct_02_m_02.h ├── struct_03.cpp ├── struct_03_m_01.h ├── struct_04.cpp ├── struct_04_m_01.h ├── struct_05.cpp ├── struct_06.cpp ├── switch_case_01.cpp ├── switch_case_02.cpp ├── test_pkg_lnn_01.cpp ├── test_pkg_lnn_02.cpp ├── union_01.cpp ├── union_02.cpp ├── vector_01.cpp └── vector_02.cpp ├── run_tests.py ├── src ├── CMakeLists.txt ├── bin │ ├── CLI11.hpp │ ├── CMakeLists.txt │ ├── lc.cpp │ └── tpl │ │ └── whereami │ │ ├── whereami.cpp │ │ └── whereami.h ├── lc │ ├── CMakeLists.txt │ ├── LC.asdl │ ├── clang_ast_to_asr.cpp │ ├── clang_ast_to_asr.h │ ├── parser │ │ ├── parser.cpp │ │ ├── parser.h │ │ ├── parser.yy │ │ ├── parser_exception.h │ │ ├── parser_stype.h │ │ ├── semantics.h │ │ ├── tokenizer.h │ │ └── tokenizer.re │ ├── utils.cpp │ └── utils.h ├── libasr │ ├── ASR.asdl │ ├── CMakeLists.txt │ ├── alloc.h │ ├── asdl.py │ ├── asdl_cpp.py │ ├── asr_builder.h │ ├── asr_scopes.cpp │ ├── asr_scopes.h │ ├── asr_utils.cpp │ ├── asr_utils.h │ ├── asr_verify.cpp │ ├── asr_verify.h │ ├── assert.h │ ├── bigint.h │ ├── bwriter.h │ ├── casting_utils.cpp │ ├── casting_utils.h │ ├── codegen │ │ ├── KaleidoscopeJIT.h │ │ ├── asr_to_c.cpp │ │ ├── asr_to_c.h │ │ ├── asr_to_c_cpp.h │ │ ├── asr_to_cpp.cpp │ │ ├── asr_to_cpp.h │ │ ├── asr_to_fortran.cpp │ │ ├── asr_to_fortran.h │ │ ├── asr_to_julia.cpp │ │ ├── asr_to_julia.h │ │ ├── asr_to_llvm.cpp │ │ ├── asr_to_llvm.h │ │ ├── asr_to_py.cpp │ │ ├── asr_to_py.h │ │ ├── asr_to_python.cpp │ │ ├── asr_to_python.h │ │ ├── asr_to_wasm.cpp │ │ ├── asr_to_wasm.h │ │ ├── asr_to_x86.cpp │ │ ├── asr_to_x86.h │ │ ├── c_evaluator.cpp │ │ ├── c_evaluator.h │ │ ├── c_utils.h │ │ ├── evaluator.cpp │ │ ├── evaluator.h │ │ ├── llvm_array_utils.cpp │ │ ├── llvm_array_utils.h │ │ ├── llvm_utils.cpp │ │ ├── llvm_utils.h │ │ ├── wasm_assembler.h │ │ ├── wasm_decoder.h │ │ ├── wasm_to_wat.cpp │ │ ├── wasm_to_wat.h │ │ ├── wasm_to_x64.cpp │ │ ├── wasm_to_x64.h │ │ ├── wasm_to_x86.cpp │ │ ├── wasm_to_x86.h │ │ ├── wasm_utils.cpp │ │ ├── wasm_utils.h │ │ ├── x86_assembler.cpp │ │ └── x86_assembler.h │ ├── colors.h │ ├── compiler_tester │ │ ├── __init__.py │ │ └── tester.py │ ├── config.h.in │ ├── containers.h │ ├── dat_convert.py │ ├── diagnostics.cpp │ ├── diagnostics.h │ ├── dwarf_convert.py │ ├── exception.h │ ├── gen_pass.py │ ├── intrinsic_func_registry_util_gen.py │ ├── location.h │ ├── lsp_interface.h │ ├── modfile.cpp │ ├── modfile.h │ ├── pass │ │ ├── arr_dims_propagate.cpp │ │ ├── arr_dims_propagate.h │ │ ├── arr_slice.cpp │ │ ├── arr_slice.h │ │ ├── array_by_data.h │ │ ├── array_op.cpp │ │ ├── array_op.h │ │ ├── class_constructor.cpp │ │ ├── class_constructor.h │ │ ├── compare.h │ │ ├── create_subroutine_from_function.h │ │ ├── dead_code_removal.cpp │ │ ├── dead_code_removal.h │ │ ├── div_to_mul.cpp │ │ ├── div_to_mul.h │ │ ├── do_loops.cpp │ │ ├── do_loops.h │ │ ├── flip_sign.cpp │ │ ├── flip_sign.h │ │ ├── fma.cpp │ │ ├── fma.h │ │ ├── for_all.cpp │ │ ├── for_all.h │ │ ├── function_call_in_declaration.cpp │ │ ├── global_stmts.cpp │ │ ├── global_stmts.h │ │ ├── global_stmts_program.cpp │ │ ├── global_stmts_program.h │ │ ├── global_symbols.cpp │ │ ├── global_symbols.h │ │ ├── implied_do_loops.cpp │ │ ├── implied_do_loops.h │ │ ├── init_expr.cpp │ │ ├── init_expr.h │ │ ├── inline_function_calls.cpp │ │ ├── inline_function_calls.h │ │ ├── insert_deallocate.cpp │ │ ├── insert_deallocate.h │ │ ├── instantiate_template.cpp │ │ ├── instantiate_template.h │ │ ├── intrinsic_array_function_registry.h │ │ ├── intrinsic_function.cpp │ │ ├── intrinsic_function.h │ │ ├── intrinsic_function_registry.h │ │ ├── intrinsic_functions.h │ │ ├── intrinsic_subroutine.cpp │ │ ├── intrinsic_subroutine_registry.h │ │ ├── intrinsic_subroutines.h │ │ ├── list_expr.h │ │ ├── loop_unroll.cpp │ │ ├── loop_unroll.h │ │ ├── loop_vectorise.cpp │ │ ├── loop_vectorise.h │ │ ├── nested_vars.cpp │ │ ├── nested_vars.h │ │ ├── param_to_const.cpp │ │ ├── param_to_const.h │ │ ├── pass_array_by_data.cpp │ │ ├── pass_array_by_data.h │ │ ├── pass_compare.cpp │ │ ├── pass_compare.h │ │ ├── pass_list_concat.cpp │ │ ├── pass_list_concat.h │ │ ├── pass_list_expr.cpp │ │ ├── pass_list_expr.h │ │ ├── pass_manager.h │ │ ├── pass_utils.cpp │ │ ├── pass_utils.h │ │ ├── print_arr.cpp │ │ ├── print_arr.h │ │ ├── print_list.cpp │ │ ├── print_list.h │ │ ├── print_list_tuple.cpp │ │ ├── print_list_tuple.h │ │ ├── print_struct_type.cpp │ │ ├── promote_allocatable_to_nonallocatable.cpp │ │ ├── promote_allocatable_to_nonallocatable.h │ │ ├── replace_arr_slice.h │ │ ├── replace_array_op.h │ │ ├── replace_class_constructor.h │ │ ├── replace_div_to_mul.h │ │ ├── replace_do_loops.h │ │ ├── replace_flip_sign.h │ │ ├── replace_fma.h │ │ ├── replace_for_all.h │ │ ├── replace_function_call_in_declaration.h │ │ ├── replace_implied_do_loops.h │ │ ├── replace_init_expr.h │ │ ├── replace_intrinsic_function.h │ │ ├── replace_intrinsic_subroutine.h │ │ ├── replace_param_to_const.h │ │ ├── replace_print_arr.h │ │ ├── replace_print_list_tuple.h │ │ ├── replace_print_struct_type.h │ │ ├── replace_select_case.h │ │ ├── replace_sign_from_value.h │ │ ├── replace_symbolic.cpp │ │ ├── replace_symbolic.h │ │ ├── replace_where.h │ │ ├── select_case.cpp │ │ ├── select_case.h │ │ ├── sign_from_value.cpp │ │ ├── sign_from_value.h │ │ ├── stmt_walk_visitor.h │ │ ├── subroutine_from_function.cpp │ │ ├── subroutine_from_function.h │ │ ├── transform_optional_argument_functions.cpp │ │ ├── transform_optional_argument_functions.h │ │ ├── unique_symbols.cpp │ │ ├── unique_symbols.h │ │ ├── unused_functions.cpp │ │ ├── unused_functions.h │ │ ├── update_array_dim_intrinsic_calls.cpp │ │ ├── update_array_dim_intrinsic_calls.h │ │ ├── where.cpp │ │ ├── where.h │ │ ├── while_else.cpp │ │ ├── while_else.h │ │ └── wrap_global_stmts.h │ ├── pickle.cpp │ ├── pickle.h │ ├── runtime │ │ ├── lfortran_intrinsics.c │ │ └── lfortran_intrinsics.h │ ├── semantic_exception.h │ ├── serialization.cpp │ ├── serialization.h │ ├── stacktrace.cpp │ ├── stacktrace.h │ ├── string_utils.cpp │ ├── string_utils.h │ ├── utils.h │ ├── utils2.cpp │ ├── wasm_instructions.txt │ └── wasm_instructions_visitor.py └── runtime │ └── legacy │ └── CMakeLists.txt └── tests ├── array_01_mdspan.cpp ├── array_02_mdspan.cpp ├── array_03.cpp ├── expr2.c ├── parse_comments_01.cpp ├── reference ├── asr-array_01-080be05.json ├── asr-array_01-080be05.stdout ├── asr-array_01_mdspan-3a0babe.json ├── asr-array_01_mdspan-3a0babe.stderr ├── asr-array_02-ec70729.json ├── asr-array_02-ec70729.stdout ├── asr-array_02_mdspan-a54a3c5.json ├── asr-array_02_mdspan-a54a3c5.stderr ├── asr-array_04-f95b8eb.json ├── asr-array_04-f95b8eb.stdout ├── asr-expr2-dda5523.json ├── asr-expr2-dda5523.stdout ├── asr-test-5bdab26.json ├── asr-test-5bdab26.stdout ├── c-expr2-6f28c3e.json ├── c-expr2-6f28c3e.stdout ├── c-test-ec3a81c.json ├── c-test-ec3a81c.stdout ├── cpp-expr2-d2bf1c6.json ├── cpp-expr2-d2bf1c6.stdout ├── cpp-test-660bf28.json ├── cpp-test-660bf28.stdout ├── fortran-expr2-98fb1e2.json ├── fortran-expr2-98fb1e2.stdout ├── fortran-test-a055f99.json ├── fortran-test-a055f99.stdout ├── llvm-expr2-94e7c35.json ├── llvm-expr2-94e7c35.stdout ├── llvm-test-63615c0.json ├── llvm-test-63615c0.stdout ├── wat-expr2-e3ba463.json ├── wat-expr2-e3ba463.stdout ├── wat-test-b9b1dc9.json └── wat-test-b9b1dc9.stdout ├── span_01.cpp ├── test.cpp └── tests.toml /.clang-format: -------------------------------------------------------------------------------- 1 | # version: 3.8 2 | # exclude: cmake/* 3 | # include: *.h 4 | # include: *.cpp 5 | 6 | Language: Cpp 7 | AccessModifierOffset: -4 8 | AlignAfterOpenBracket: true 9 | AlignConsecutiveAssignments: false 10 | AlignEscapedNewlinesLeft: false 11 | AlignOperands: true 12 | AlignTrailingComments: true 13 | AllowAllParametersOfDeclarationOnNextLine: true 14 | AllowShortBlocksOnASingleLine: false 15 | AllowShortCaseLabelsOnASingleLine: false 16 | AllowShortFunctionsOnASingleLine: Empty 17 | AllowShortIfStatementsOnASingleLine: false 18 | AllowShortLoopsOnASingleLine: false 19 | AlwaysBreakAfterDefinitionReturnType: None 20 | AlwaysBreakBeforeMultilineStrings: false 21 | AlwaysBreakTemplateDeclarations: true 22 | BinPackArguments: true 23 | BinPackParameters: true 24 | BreakBeforeBinaryOperators: All 25 | BreakBeforeBraces: Custom 26 | BreakBeforeTernaryOperators: true 27 | BreakConstructorInitializersBeforeComma: false 28 | ColumnLimit: 80 29 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 30 | ConstructorInitializerIndentWidth: 4 31 | ContinuationIndentWidth: 4 32 | Cpp11BracedListStyle: true 33 | DerivePointerAlignment: false 34 | DisableFormat: false 35 | ExperimentalAutoDetectBinPacking: false 36 | IndentCaseLabels: true 37 | IndentWidth: 4 38 | IndentWrappedFunctionNames: false 39 | KeepEmptyLinesAtTheStartOfBlocks: true 40 | MacroBlockBegin: '' 41 | MacroBlockEnd: '' 42 | MaxEmptyLinesToKeep: 1 43 | NamespaceIndentation: None 44 | ObjCBlockIndentWidth: 2 45 | ObjCSpaceAfterProperty: false 46 | ObjCSpaceBeforeProtocolList: true 47 | PenaltyBreakBeforeFirstCallParameter: 19 48 | PenaltyBreakComment: 22312 49 | PenaltyBreakFirstLessLess: 120 50 | PenaltyBreakString: 2123 51 | PenaltyExcessCharacter: 1000000 52 | PenaltyReturnTypeOnItsOwnLine: 60 53 | PointerAlignment: Right 54 | SortIncludes: false 55 | SpaceAfterCStyleCast: false 56 | SpaceBeforeAssignmentOperators: true 57 | SpaceBeforeParens: ControlStatements 58 | SpaceInEmptyParentheses: false 59 | SpacesBeforeTrailingComments: 1 60 | SpacesInAngles: false 61 | SpacesInContainerLiterals: false 62 | SpacesInCStyleCastParentheses: false 63 | SpacesInParentheses: false 64 | SpacesInSquareBrackets: false 65 | Standard: Cpp11 66 | TabWidth: 4 67 | UseTab: Never 68 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags: 8 | - 'v*' 9 | pull_request: 10 | branches: 11 | - main 12 | 13 | jobs: 14 | Build: 15 | name: LFortran CI (${{ matrix.os }}) 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | os: ["ubuntu-latest", "macos-latest"] 21 | steps: 22 | - uses: actions/checkout@v3 23 | with: 24 | fetch-depth: 0 25 | 26 | - uses: mamba-org/setup-micromamba@v1 27 | with: 28 | environment-file: environment_unix.yml 29 | 30 | - uses: hendrikmuhs/ccache-action@main 31 | with: 32 | variant: sccache 33 | key: ${{ github.job }}-${{ matrix.os }} 34 | 35 | - name: Build (Linux / macOS) 36 | shell: bash -l {0} 37 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 38 | run: | 39 | ./build.sh 40 | export PATH=$CONDA_PREFIX/bin:$PATH 41 | 42 | - name: Print runtime library directory 43 | shell: bash -l {0} 44 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 45 | run: | 46 | lc --get-rtl-header-dir 47 | lc --get-rtl-dir 48 | 49 | - name: Test (Linux / macOS) 50 | shell: bash -l -e {0} 51 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 52 | run: | 53 | export CPATH=$CONDA_PREFIX/include:$CPATH 54 | git clone https://github.com/czgdp1807/mdspan 55 | cd mdspan 56 | cmake . -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX 57 | make install 58 | cd .. 59 | lc --show-clang-ast tests/test.cpp 60 | lc --show-clang-ast --parse-all-comments tests/parse_comments_01.cpp > parse_comments_01.stdout 61 | grep "TextComment" parse_comments_01.stdout 62 | rm parse_comments_01.stdout 63 | lc examples/expr2.c --show-asr 64 | ./run_tests.py 65 | 66 | - name: Test2 (Linux / macOS) 67 | shell: bash -l -e {0} 68 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 69 | run: | 70 | which clang 71 | 72 | # Test generating object files 73 | lc examples/expr2.c --backend c -o c_o -c 74 | lc examples/expr2.c --backend llvm -o llvm_o -c 75 | ls -1 76 | cd examples 77 | lc expr2.c 78 | 79 | - name: Test3 (Linux / macOS) 80 | shell: bash -l -e {0} 81 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 82 | run: | 83 | export CPATH=$CONDA_PREFIX/include:$CPATH 84 | ./integration_tests/run_tests.py -b gcc llvm wasm c 85 | ./integration_tests/run_tests.py -b gcc llvm wasm c -f 86 | 87 | - name: Test4 (Linux) 88 | shell: bash -l -e {0} 89 | if: contains(matrix.os, 'ubuntu') 90 | run: | 91 | export CPATH=$CONDA_PREFIX/include:$CPATH 92 | conda install --yes pytorch::pytorch 93 | cp -r $CONDA_PREFIX/lib/python3.12/site-packages/torch/include/* $CONDA_PREFIX/include/ 94 | cp -r $CONDA_PREFIX/lib/python3.12/site-packages/torch/lib/* $CONDA_PREFIX/lib/ 95 | cp -r $CONDA_PREFIX/lib/python3.12/site-packages/torch/share/* $CONDA_PREFIX/share/ 96 | ./integration_tests/run_tests.py -b pytorch 97 | export CPATH=$CPATH:$CONDA_PREFIX/include/torch/csrc/api/include 98 | ./integration_tests/run_tests.py -b llvmPytorch 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## CMake 2 | CMakeCache.txt 3 | CMakeFiles/ 4 | Makefile 5 | CTestTestfile.cmake 6 | cmake_install.cmake 7 | install_manifest.txt 8 | Testing/Temporary 9 | CPackConfig.cmake 10 | CPackSourceConfig.cmake 11 | _CPack_Packages 12 | /CMakeSettings.json 13 | src/libasr/libasr.a.* 14 | build/ 15 | *.DS_Store* 16 | *.ast 17 | 18 | ## libraries 19 | *.a 20 | *.so 21 | *.s 22 | *.ll 23 | *.dylib 24 | *.dSYM 25 | 26 | ## Generated files 27 | src/lc/ast.h 28 | src/lc/parser/tokenizer.cpp 29 | src/lc/parser/parser.output 30 | src/lc/parser/parser.tab.cc 31 | src/lc/parser/parser.tab.hh 32 | src/libasr/asr.h 33 | src/libasr/wasm_visitor.h 34 | src/libasr/pass/intrinsic_function_registry_util.h 35 | src/libasr/config.h 36 | fa 37 | fa2 38 | c_o 39 | llvm_o 40 | */bin/lc 41 | *vscode* 42 | integration_tests/test-* 43 | 44 | ## Byte-compiled / optimized / DLL files 45 | __pycache__/ 46 | 47 | ## Output files 48 | output 49 | *__generated__.* 50 | *.out 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Ondřej Čertík 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LC 2 | 3 | LC is the C and C++ frontend to LCompilers. 4 | 5 | # Build and Run 6 | 7 | mamba env create -f environment_unix.yml 8 | conda activate lc 9 | ./build.sh 10 | lc examples/expr2.c 11 | lc --show-clang-ast examples/expr2.c 12 | lc --show-asr examples/expr2.c 13 | lc --show-llvm examples/expr2.c 14 | 15 | # Tests 16 | 17 | To run tests, do: 18 | 19 | CPATH=$CONDA_PREFIX/include ./run_tests.py 20 | cd integration_tests 21 | CPATH=$CONDA_PREFIX/include ./run_tests.py 22 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | python src/libasr/asdl_cpp.py src/lc/LC.asdl src/lc/ast.h 6 | python src/libasr/asdl_cpp.py src/libasr/ASR.asdl src/libasr/asr.h 7 | python src/libasr/wasm_instructions_visitor.py 8 | python src/libasr/intrinsic_func_registry_util_gen.py 9 | 10 | (cd src/lc/parser && re2c -W -b tokenizer.re -o tokenizer.cpp) 11 | (cd src/lc/parser && bison -Wall -d -r all parser.yy) 12 | 13 | cmake \ 14 | -DCMAKE_BUILD_TYPE=Debug \ 15 | -DWITH_LLVM=yes \ 16 | -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ 17 | . 18 | cmake --build . -j16 --target install 19 | -------------------------------------------------------------------------------- /cmake/FindMACHO.cmake: -------------------------------------------------------------------------------- 1 | find_path(MACHO_INCLUDE_DIR mach-o/dyld.h) 2 | 3 | include(FindPackageHandleStandardArgs) 4 | find_package_handle_standard_args(MACHO DEFAULT_MSG MACHO_INCLUDE_DIR) 5 | 6 | add_library(p::macho INTERFACE IMPORTED) 7 | set_property(TARGET p::macho PROPERTY INTERFACE_INCLUDE_DIRECTORIES 8 | ${MACHO_INCLUDE_DIR}) 9 | -------------------------------------------------------------------------------- /cmake/Findclang.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 Andrew Kelley 2 | # This file is MIT licensed. 3 | # See http://opensource.org/licenses/MIT 4 | 5 | # CLANG_FOUND 6 | # CLANG_INCLUDE_DIRS 7 | # CLANG_LIBRARIES 8 | # CLANG_LIBDIRS 9 | 10 | find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h) 11 | 12 | macro(FIND_AND_ADD_CLANG_LIB _libname_) 13 | string(TOUPPER ${_libname_} _prettylibname_) 14 | find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} NAMES_PER_DIR) 15 | if(CLANG_${_prettylibname_}_LIB) 16 | set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB}) 17 | endif() 18 | endmacro(FIND_AND_ADD_CLANG_LIB) 19 | 20 | FIND_AND_ADD_CLANG_LIB(clangFrontendTool) 21 | FIND_AND_ADD_CLANG_LIB(clangCodeGen) 22 | FIND_AND_ADD_CLANG_LIB(clangFrontend) 23 | FIND_AND_ADD_CLANG_LIB(clangDriver) 24 | FIND_AND_ADD_CLANG_LIB(clangSerialization) 25 | FIND_AND_ADD_CLANG_LIB(clangSema) 26 | FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerFrontend) 27 | FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCheckers) 28 | FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCore) 29 | FIND_AND_ADD_CLANG_LIB(clangAnalysis) 30 | FIND_AND_ADD_CLANG_LIB(clangASTMatchers) 31 | FIND_AND_ADD_CLANG_LIB(clangCrossTU) 32 | FIND_AND_ADD_CLANG_LIB(clangAST) 33 | FIND_AND_ADD_CLANG_LIB(clangParse) 34 | FIND_AND_ADD_CLANG_LIB(clangSema) 35 | FIND_AND_ADD_CLANG_LIB(clangBasic) 36 | FIND_AND_ADD_CLANG_LIB(clangEdit) 37 | FIND_AND_ADD_CLANG_LIB(clangLex) 38 | FIND_AND_ADD_CLANG_LIB(clangARCMigrate) 39 | FIND_AND_ADD_CLANG_LIB(clangRewriteFrontend) 40 | FIND_AND_ADD_CLANG_LIB(clangRewrite) 41 | FIND_AND_ADD_CLANG_LIB(clangIndex) 42 | FIND_AND_ADD_CLANG_LIB(clangToolingCore) 43 | FIND_AND_ADD_CLANG_LIB(clangToolingSyntax) 44 | FIND_AND_ADD_CLANG_LIB(clangTooling) 45 | FIND_AND_ADD_CLANG_LIB(clangExtractAPI) 46 | FIND_AND_ADD_CLANG_LIB(clangSupport) 47 | 48 | include(FindPackageHandleStandardArgs) 49 | find_package_handle_standard_args(clang DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS) 50 | 51 | mark_as_advanced(CLANG_INCLUDE_DIRS CLANG_LIBRARIES CLANG_LIBDIRS) 52 | -------------------------------------------------------------------------------- /cmake/UserOverride.cmake: -------------------------------------------------------------------------------- 1 | # This overrides the default CMake Debug and Release compiler options. 2 | # The user can still specify different options by setting the 3 | # CMAKE_CXX_FLAGS_[RELEASE,DEBUG] variables (on the command line or in the 4 | # CMakeList.txt). This files serves as better CMake defaults and should only be 5 | # modified if the default values are to be changed. Project specific compiler 6 | # flags should be set in the CMakeList.txt by setting the CMAKE_CXX_FLAGS_* 7 | # variables. 8 | 9 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 10 | # g++ 11 | set(common "-Wall -Wextra") 12 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -funroll-loops -DNDEBUG") 13 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb") 14 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") 15 | # icpc 16 | set(common "-Wall") 17 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -xHOST -O3") 18 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -O0") 19 | elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) 20 | # clang 21 | set(common "-Wall -Wextra") 22 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -funroll-loops -DNDEBUG") 23 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb") 24 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") 25 | # pgcpp 26 | endif () 27 | -------------------------------------------------------------------------------- /environment_unix.yml: -------------------------------------------------------------------------------- 1 | name: lc 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - cmake=3.27.9 6 | - llvmdev=16.0.6 7 | - clangdev=16.0.6 8 | - compilers=1.7.0 9 | - make=4.3 10 | - zlib=1.2.13 11 | - git=2.43.0 12 | - python=3.12.0 13 | - toml=0.10.2 14 | - xtensor=0.24.7 15 | - bison=3.4 16 | - re2c=3.1 17 | -------------------------------------------------------------------------------- /examples/expr2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int x; 5 | x = (2+3)*5; 6 | printf("%d\n", x); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /integration_tests/array_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int arr1d[5] = { 1, 2, 3, 4, 5 }; 6 | int arr2d[4][3][2] = { 7 | {{1, 2}, {3, 4}, {5, 6}}, 8 | {{8, 9}, {10, 11}, {12, 13}}, 9 | {{14, 15}, {16, 17}, {18, 19}}, 10 | {{20, 21}, {22, 23}, {24, 25}} 11 | }; 12 | int sum1d = 0, sum2d = 0; 13 | 14 | for( int i = 0; i < 5; i++ ) { 15 | sum1d += arr1d[i]; 16 | } 17 | 18 | for( int j = 0; j < 4; j++ ) { 19 | for( int k = 0; k < 3; k++ ) { 20 | for( int l = 0; l < 2; l++ ) { 21 | sum2d += arr2d[j][k][l]; 22 | } 23 | } 24 | } 25 | 26 | printf("%d %d\n", sum1d, sum2d); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /integration_tests/array_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define M 4 4 | #define N 10 5 | #define NUM 4 6 | 7 | float matmul_test(int m, int n, int nums) { 8 | float arr1d[n]; 9 | float arr2d[nums][m][n]; 10 | float sum; 11 | for( int num = 0; num < nums; num++ ) { 12 | for( int i = 0; i < m; i++ ) { 13 | for( int j = 0; j < n; j++ ) { 14 | arr2d[num][i][j] = (float) (i + j) / (float) (m * n); 15 | } 16 | } 17 | } 18 | 19 | for( int k = 0; k < n; k++ ) { 20 | arr1d[k] = (float) k / (float) n; 21 | } 22 | 23 | sum = 0.0; 24 | for( int num = 0; num < nums; num++ ) { 25 | for( int i = 0; i < M; i++ ) { 26 | float output = 0.0; 27 | for( int j = 0; j < N; j++ ) { 28 | output += arr2d[num][i][j] * arr1d[j]; 29 | } 30 | sum += output; 31 | } 32 | } 33 | return sum; 34 | } 35 | 36 | int main() 37 | { 38 | float sum = matmul_test(M, N, NUM); 39 | printf("%f\n", sum); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /integration_tests/array_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "xtensor/xtensor.hpp" 3 | #include "xtensor/xio.hpp" 4 | #include "xtensor/xview.hpp" 5 | 6 | int main() { 7 | 8 | xt::xtensor arr1; /* { // TODO: Uncomment this initializer 9 | {1.0, 2.0, 3.0}, 10 | {2.0, 5.0, 7.0}, 11 | {2.0, 5.0, 7.0}}; */ 12 | 13 | xt::xtensor arr2 {5.0, 6.0, 7.0}; 14 | 15 | // xt::xarray res = xt::view(arr1, 1) + arr2; // TODO: Uncomment this statement 16 | std::cout << arr2; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /integration_tests/array_03_mdspan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void print(Kokkos::mdspan>& arr) { 6 | for( int32_t i = 0; i < arr.size(); i++ ) { 7 | std::cout << arr[i] << "\n"; 8 | } 9 | } 10 | 11 | int main() { 12 | 13 | std::vector arr1_data = {1.0, 2.0, 3.0, 2.0, 5.0, 7.0, 2.0, 5.0, 7.0}; 14 | std::vector arr2_data = {5.0, 6.0, 7.0}; 15 | 16 | Kokkos::mdspan> arr1{arr1_data.data(), 3, 3}; 17 | 18 | Kokkos::mdspan> arr2{arr2_data.data(), 3}; 19 | 20 | print( arr2 ); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /integration_tests/array_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xtensor/xtensor.hpp" 4 | #include "xtensor/xio.hpp" 5 | #include "xtensor/xview.hpp" 6 | 7 | int main() { 8 | 9 | xt::xtensor arr1 { 10 | {1.0, 2.0, 3.0}, 11 | {2.0, 5.0, 7.0}, 12 | {2.0, 5.0, 7.0}}; 13 | 14 | xt::xtensor arr2 {5.0, 6.0, 7.0}; 15 | xt::xtensor res; 16 | xt::xtensor_fixed> res_ = {7.0, 11.0, 14.0}; 17 | 18 | res = xt::empty({3}); 19 | res = xt::view(arr1, 1) + arr2; 20 | std::cout << arr1 << "\n"; 21 | std::cout << arr2 << "\n"; 22 | std::cout << res << "\n"; 23 | 24 | if( xt::any(xt::abs(res - res_) > 1e-8) ) { 25 | exit(2); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /integration_tests/array_04_mdspan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void print2(Kokkos::mdspan>& arr) { 6 | for( int32_t i = 0; i < arr.extent(0); i++ ) { 7 | for( int32_t j = 0; j < arr.extent(1) ; j++ ) { 8 | std::cout << arr(i, j) << " "; 9 | } 10 | } 11 | } 12 | 13 | void print1(Kokkos::mdspan>& arr) { 14 | for( int32_t i = 0; i < arr.size(); i++ ) { 15 | std::cout << arr[i] << " "; 16 | } 17 | std::cout << "\n"; 18 | } 19 | 20 | int main() { 21 | 22 | std::vector arr1_data = {1.0, 2.0, 3.0, 2.0, 5.0, 7.0, 2.0, 5.0, 7.0}; 23 | Kokkos::mdspan> arr1(arr1_data.data(), 3, 3); 24 | 25 | std::vector arr2_data = {5.0, 6.0, 7.0}; 26 | Kokkos::mdspan> arr2(arr2_data.data(), 3); 27 | Kokkos::mdspan> res; 28 | std::vector res_data_correct = {7.0, 11.0, 14.0}; 29 | 30 | std::vector res_data; res_data.reserve(3); 31 | res = Kokkos::mdspan>(res_data.data()); 32 | res = Kokkos::submdspan(arr1, 1, Kokkos::full_extent); 33 | for( int32_t i = 0; i < res.size(); i++ ) { 34 | res[i] = res[i] + arr2[i]; 35 | } 36 | 37 | print2(arr1); 38 | print1(arr2); 39 | print1(res); 40 | 41 | 42 | for( int32_t i = 0; i < res.size(); i++ ) { 43 | if( res[i] != res_data_correct[i] ) { 44 | exit(2); 45 | } 46 | } 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /integration_tests/array_05.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xtensor/xio.hpp" 4 | #include "xtensor/xview.hpp" 5 | 6 | int main() { 7 | 8 | xt::xtensor_fixed> arr1; 9 | xt::xtensor arr2 {5.0, 6.0, 7.0}; 10 | xt::xtensor_fixed> result; 11 | 12 | for( int i = 0; i < 3; i++ ) { 13 | for( int j = 0; j < 3; j++ ) { 14 | arr1(i, j) = i*3 + j; 15 | } 16 | } 17 | 18 | std::cout << arr1 << arr2 << std::endl; 19 | result = xt::view(arr1, 1) + arr2; 20 | std::cout << result << std::endl; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /integration_tests/array_06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xtensor/xio.hpp" 4 | #include "xtensor/xview.hpp" 5 | 6 | double reduce_array(xt::xtensor_fixed>& arr) { 7 | double sum = 0.0; 8 | for( int i = 0; i < arr.shape(0); i++ ) { 9 | for( int j = 0; j < arr.shape(1); j++ ) { 10 | sum += arr(i, j); 11 | } 12 | } 13 | return sum; 14 | } 15 | 16 | int main() { 17 | 18 | xt::xtensor_fixed> arr1; 19 | double result; 20 | 21 | for( int i = 0; i < 3; i++ ) { 22 | for( int j = 0; j < 3; j++ ) { 23 | arr1(i, j) = i*3 + j; 24 | } 25 | } 26 | 27 | std::cout << arr1 << std::endl; 28 | result = reduce_array(arr1); 29 | std::cout << result << std::endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /integration_tests/array_07.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xtensor/xio.hpp" 4 | #include "xtensor/xview.hpp" 5 | 6 | xt::xtensor_fixed> matmul( 7 | xt::xtensor_fixed>& a, 8 | xt::xtensor_fixed>& b) { 9 | xt::xtensor_fixed> ab; 10 | for( int i = 0; i < a.shape(0); i++ ) { 11 | for( int j = 0; j < b.shape(1); j++ ) { 12 | ab(i, j) = 0; 13 | for( int k = 0; k < a.shape(1); k++ ) { 14 | ab(i, j) += a(i, k) * b(k, j); 15 | } 16 | } 17 | } 18 | return ab; 19 | } 20 | 21 | int main() { 22 | 23 | xt::xtensor_fixed> a; 24 | xt::xtensor_fixed> b; 25 | xt::xtensor_fixed> c; 26 | 27 | for( int i = 0; i < a.shape(0); i++ ) { 28 | for( int j = 0; j < a.shape(1); j++ ) { 29 | a(i, j) = i * a.shape(0) * j; 30 | } 31 | } 32 | 33 | for( int i = 0; i < b.shape(0); i++ ) { 34 | for( int j = 0; j < b.shape(1); j++ ) { 35 | b(i, j) = i * b.shape(0) * j; 36 | } 37 | } 38 | 39 | std::cout << a << b << std::endl; 40 | c = matmul(a, b); 41 | std::cout << c << std::endl; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /integration_tests/array_08.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xtensor/xio.hpp" 4 | #include "xtensor/xview.hpp" 5 | 6 | xt::xtensor matmul( 7 | xt::xtensor& a, 8 | xt::xtensor& b) { 9 | xt::xtensor ab = xt::empty({a.shape(0), b.shape(1)}); 10 | for( int i = 0; i < a.shape(0); i++ ) { 11 | for( int j = 0; j < b.shape(1); j++ ) { 12 | ab(i, j) = 0; 13 | for( int k = 0; k < a.shape(1); k++ ) { 14 | ab(i, j) += a(i, k) * b(k, j); 15 | } 16 | } 17 | } 18 | return ab; 19 | } 20 | 21 | int main() { 22 | 23 | xt::xtensor a = xt::empty({3, 2}); 24 | xt::xtensor b = xt::empty({2, 3}); 25 | xt::xtensor c = xt::empty({3, 3}); 26 | xt::xtensor ce = { 27 | {0.0, 0.0, 0.0}, 28 | {0.0, 6.0, 12.0}, 29 | {0.0, 12.0, 24.0}}; 30 | 31 | for( int i = 0; i < a.shape(0); i++ ) { 32 | for( int j = 0; j < a.shape(1); j++ ) { 33 | a(i, j) = i * a.shape(0) * j; 34 | } 35 | } 36 | 37 | for( int i = 0; i < b.shape(0); i++ ) { 38 | for( int j = 0; j < b.shape(1); j++ ) { 39 | b(i, j) = i * b.shape(0) * j; 40 | } 41 | } 42 | 43 | std::cout << a << b << std::endl; 44 | c = matmul(a, b); 45 | std::cout << c << std::endl; 46 | for( int i = 0; i < c.shape(0); i++ ) { 47 | for( int j = 0; j < c.shape(1); j++ ) { 48 | if( c(i, j) != ce(i, j) ) { 49 | exit(2); 50 | } 51 | } 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /integration_tests/array_09.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "xtensor/xio.hpp" 5 | #include "xtensor/xview.hpp" 6 | 7 | int main() { 8 | 9 | xt::xtensor g; 10 | xt::xtensor y; 11 | xt::xtensor_fixed> b; 12 | int i; 13 | 14 | y = xt::empty({20, 20}); 15 | g = xt::empty({20}); 16 | 17 | b.fill(2); 18 | y.fill(4); 19 | g.fill(8); 20 | 21 | std::cout << b << y << g << std::endl; 22 | 23 | for( i = 0 ; i < 20; i++ ) { 24 | xt::view(y, i) = xt::view(g, xt::all()) * xt::view(y, i) + xt::view(b, xt::all()); 25 | } 26 | 27 | std::cout<< y << std::endl; 28 | if( xt::any(xt::not_equal(y, 34)) ) { 29 | exit(2); 30 | } 31 | 32 | return 0; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /integration_tests/array_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "xtensor/xio.hpp" 5 | #include "xtensor/xview.hpp" 6 | 7 | xt::xtensor softmax(xt::xtensor& x) { 8 | xt::xtensor y = xt::empty({x.shape(0), x.shape(1)}); 9 | int i; 10 | double s; 11 | 12 | for( int i = 0; i < x.shape(1); i++ ) { 13 | xt::view(y, xt::all(), i) = xt::exp(xt::view(x, xt::all(), i) - xt::amax(xt::view(x, xt::all(), i))); 14 | xt::view(y, xt::all(), i) = xt::view(y, xt::all(), i) / xt::sum(xt::view(y, xt::all(), i)); 15 | } 16 | 17 | return y; 18 | } 19 | 20 | int main() { 21 | 22 | xt::xtensor x = xt::empty({10, 10}); 23 | // xt::xtensor sx = xt::empty({10, 10}); // Uncomment, bug in IntrinsicScalarFunctions::Abs 24 | xt::xtensor_fixed> sx; 25 | 26 | x.fill(2.0); 27 | 28 | sx = softmax(x); 29 | std::cout<< sx << std::endl; 30 | if( xt::any(xt::abs(sx - 0.1) > 1e-6) ) { 31 | exit(2); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /integration_tests/array_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "xtensor/xio.hpp" 5 | #include "xtensor/xview.hpp" 6 | 7 | int main() { 8 | xt::xtensor_fixed> R; 9 | xt::xtensor_fixed> V; 10 | xt::xtensor_fixed> U; 11 | R.fill(23); 12 | V.fill(9); 13 | U.fill(1); 14 | 15 | xt::view(R, xt::range(1, 4, 1)) = xt::view(V, xt::range(1, 4)) * 1 * xt::view(U, xt::range(1, 4)); 16 | 17 | std::cout<< R << std::endl; 18 | if (R(0) != 23) { 19 | exit(2); 20 | } 21 | if (R(1) != 9) { 22 | exit(2); 23 | } 24 | if (R(2) != 9) { 25 | exit(2); 26 | } 27 | if (R(3) != 9) { 28 | exit(2); 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /integration_tests/array_12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "xtensor/xio.hpp" 5 | #include "xtensor/xview.hpp" 6 | 7 | xt::xtensor func(const xt::xtensor& R, const xt::xtensor& V) { 8 | xt::xtensor Vmid = xt::empty({R.shape(0) - 1}); 9 | int i; 10 | 11 | for( i = 0; i < Vmid.shape(0); i++ ) { 12 | Vmid(i) = R(i)*V(i); 13 | } 14 | 15 | return Vmid; 16 | } 17 | 18 | int main() { 19 | 20 | xt::xtensor_fixed> R; 21 | xt::xtensor_fixed> V; 22 | xt::xtensor_fixed> Vmid; 23 | 24 | R.fill(45.0); 25 | V.fill(23.0); 26 | 27 | xt::view(Vmid, xt::range(0, 3)) = func(xt::view(R, xt::range(0, 4)), xt::view(V, xt::range(0, 4))); 28 | std::cout << Vmid << std::endl; 29 | if( xt::any(xt::not_equal(Vmid, 1035.00)) ) { 30 | exit(2); 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /integration_tests/array_13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | #include "xtensor/xview.hpp" 7 | 8 | xt::xtensor R3(const xt::xtensor& x) { 9 | xt::xtensor R3_ = xt::empty({x.size()}); 10 | 11 | double a, b; 12 | const double c = 2.0; 13 | a = x(0); 14 | b = x(1); 15 | R3_.fill(std::pow(a, 2.0) + std::pow(b, 2.0) - std::pow(c, 2.0)); 16 | 17 | return R3_; 18 | } 19 | 20 | int main() { 21 | 22 | xt::xtensor_fixed> x = {0.5, 0.5}; 23 | std::cout << R3(x) << std::endl; 24 | if( xt::any(xt::not_equal(R3(x), -3.5)) ) { 25 | exit(2); 26 | } 27 | 28 | return 0; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /integration_tests/array_14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | #include "xtensor/xview.hpp" 7 | 8 | int main() { 9 | 10 | xt::xtensor array_const_1 = {{-14, 3, 0, -2}, {19, 1, 20, 21}}; 11 | xt::xtensor_fixed> i23_shape = {4, 2}; 12 | std::cout<< array_const_1 << "\n"; 13 | array_const_1.reshape(i23_shape); 14 | std::cout << array_const_1 << "\n"; 15 | std::cout << array_const_1(0, 0) << " " << array_const_1(0, 1) << "\n"; 16 | std::cout << array_const_1(1, 0) << " " << array_const_1(1, 1) << "\n"; 17 | std::cout << array_const_1(2, 0) << " " << array_const_1(2, 1) << "\n"; 18 | std::cout << array_const_1(3, 0) << " " << array_const_1(3, 1) << "\n"; 19 | if( array_const_1(0, 0) != -14 ) { 20 | exit(2); 21 | } 22 | if( array_const_1(0, 1) != 3 ) { 23 | exit(2); 24 | } 25 | if( array_const_1(1, 0) != 0 ) { 26 | exit(2); 27 | } 28 | if( array_const_1(1, 1) != -2 ) { 29 | exit(2); 30 | } 31 | if( array_const_1(2, 0) != 19 ) { 32 | exit(2); 33 | } 34 | if( array_const_1(2, 1) != 1 ) { 35 | exit(2); 36 | } 37 | if( array_const_1(3, 0) != 20 ) { 38 | exit(2); 39 | } 40 | if( array_const_1(3, 1) != 21 ) { 41 | exit(2); 42 | } 43 | 44 | return 0; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /integration_tests/array_15.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | #include "xtensor/xview.hpp" 7 | 8 | void check(const xt::xtensor& c, const xt::xtensor& a, 9 | const xt::xtensor& b, const int op_code) { 10 | 11 | int i, j, k; 12 | 13 | std::cout << c << std::endl; 14 | 15 | for( i = 0; i < a.shape(0); i++ ) { 16 | for( j = 0; j < a.shape(1); j++ ) { 17 | for( k = 0; k < a.shape(2); k++ ) { 18 | switch( op_code ) { 19 | case 0: { 20 | if(c(i, j, k) != (a(i, j, k) == b(i, j, k))) { 21 | exit(2); 22 | } 23 | break; 24 | } 25 | case 1: { 26 | if(c(i, j, k) != (a(i, j, k) != b(i, j, k))) { 27 | exit(2); 28 | } 29 | break; 30 | } 31 | case 2: { 32 | if(c(i, j, k) != (a(i, j, k) < b(i, j, k))) { 33 | exit(2); 34 | } 35 | break; 36 | } 37 | case 3: { 38 | if(c(i, j, k) != (b(i, j, k) <= a(i, j, k))) { 39 | exit(2); 40 | } 41 | break; 42 | } 43 | case 4: { 44 | if(c(i, j, k) != (b(i, j, k) > a(i, j, k))) { 45 | exit(2); 46 | } 47 | break; 48 | } 49 | case 5: { 50 | if(c(i, j, k) != (b(i, j, k) >= a(i, j, k))) { 51 | exit(2); 52 | } 53 | break; 54 | } 55 | default: { 56 | exit(2); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | } 64 | 65 | int main() { 66 | 67 | xt::xtensor a = xt::empty({2, 2, 1}); 68 | xt::xtensor b = xt::empty({2, 2, 1}); 69 | xt::xtensor c = xt::empty({2, 2, 1}); 70 | int i, j, k; 71 | 72 | for( i = 0; i < 2; i++ ) { 73 | for( j = 0; j < 2; j++ ) { 74 | for( k = 0; k < 1; k++ ) { 75 | a(i, j, k) = (i + 1)/(j + 1); 76 | b(i, j, k) = (j + 1)/(i + 1); 77 | } 78 | } 79 | } 80 | 81 | std::cout << a << std::endl; 82 | std::cout << b << std::endl; 83 | 84 | c = xt::equal(a, b); 85 | check(c, a, b, 0); 86 | 87 | c = xt::not_equal(a, b); 88 | check(c, a, b, 1); 89 | 90 | c = (a < b); 91 | check(c, a, b, 2); 92 | 93 | c = (b <= a); 94 | check(c, a, b, 3); 95 | 96 | c = (b > a); 97 | check(c, a, b, 4); 98 | 99 | c = (b >= a); 100 | check(c, a, b, 5); 101 | 102 | } 103 | -------------------------------------------------------------------------------- /integration_tests/array_16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | #include "xtensor/xview.hpp" 7 | 8 | using namespace std::complex_literals; 9 | 10 | void check(const xt::xtensor, 3>& c, const int op_code) { 11 | 12 | int i, j, k; 13 | double left, right; 14 | 15 | std::cout << c << std::endl; 16 | 17 | for( i = 0; i < c.shape(0); i++ ) { 18 | for( j = 0; j < c.shape(1); j++ ) { 19 | for( k = 0; k < c.shape(2); k++ ) { 20 | left = i + j + k + 3; 21 | right = (i + 1)*(j + 1)*(k + 1); 22 | switch( op_code ) { 23 | case 0: { 24 | if(c(i, j, k) != left + right*1.0i) { 25 | exit(2); 26 | } 27 | break; 28 | } 29 | case 1: { 30 | if(c(i, j, k) != -left - right*1.0i) { 31 | exit(2); 32 | } 33 | break; 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | } 41 | 42 | int main() { 43 | 44 | xt::xtensor_fixed> a; 45 | xt::xtensor_fixed> b; 46 | xt::xtensor, 3> c = xt::empty>({2, 2, 1}); 47 | int i, j, k; 48 | 49 | for( i = 0; i < 2; i++ ) { 50 | for( j = 0; j < 2; j++ ) { 51 | for( k = 0; k < 1; k++ ) { 52 | a(i, j, k) = i + j + k + 3; 53 | b(i, j, k) = (i + 1)*(j + 1)*(k + 1); 54 | } 55 | } 56 | } 57 | 58 | std::cout << a << std::endl; 59 | std::cout << b << std::endl; 60 | 61 | c = a + 1.0i*b; 62 | check(c, 0); 63 | 64 | c = -a + 1.0i*(-b); 65 | check(c, 1); 66 | 67 | return 0; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /integration_tests/array_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | xt::xtensor solution() { 6 | xt::xtensor x; 7 | x = {1.0, 1.0}; 8 | return x; 9 | } 10 | 11 | 12 | void compare_solutions() { 13 | int i; 14 | xt::xtensor_fixed> x; 15 | 16 | std::cout << solution().size() << std::endl; 17 | 18 | for( i = 0; i < solution().size(); i++ ) { 19 | x(i) = i; 20 | } 21 | 22 | for( i = 0; i < 2; i++ ) { 23 | std::cout << x(i) << std::endl; 24 | if( x(i) != i ) { 25 | exit(2); 26 | } 27 | } 28 | } 29 | 30 | int main() { 31 | 32 | compare_solutions(); 33 | 34 | return 0; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /integration_tests/array_18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | 7 | xt::xtensor solution(); 8 | void compare_solutions(const xt::xtensor& y); 9 | 10 | xt::xtensor solution() { 11 | xt::xtensor x = xt::empty({2}); 12 | x = {1.0, 2.0}; 13 | return x; 14 | } 15 | 16 | void compare_solutions(const xt::xtensor& x) { 17 | xt::xtensor diff = xt::empty({x.size()}); 18 | 19 | diff = solution() - x; 20 | 21 | std::cout << diff << std::endl; 22 | 23 | if (std::abs(diff(0) - 0.0) > 1e-6) { 24 | exit(2); 25 | } 26 | if (std::abs(diff(0) - 0.0) > 1e-6) { 27 | exit(2); 28 | } 29 | 30 | diff = x - solution(); 31 | 32 | std::cout << diff << std::endl; 33 | 34 | if (diff(0) != 0.0) { 35 | exit(2); 36 | } 37 | if (diff(1) != 0.0) { 38 | exit(2); 39 | } 40 | } 41 | 42 | int main() { 43 | 44 | xt::xtensor z = xt::empty({2}); 45 | 46 | std::cout << solution() << std::endl; 47 | z = solution(); 48 | std::cout << z << std::endl; 49 | compare_solutions(z); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /integration_tests/array_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | 7 | void copy_from_to(const xt::xtensor_fixed>& xa, 8 | xt::xtensor_fixed>&xb) { 9 | int i; 10 | for( i = 0; i < xa.size(); i++ ) { 11 | xb(i) = xa(i); 12 | } 13 | } 14 | 15 | bool verify(const xt::xtensor_fixed>& a, 16 | const xt::xtensor_fixed>& b) { 17 | int i; 18 | bool r = true; 19 | for( i = 0; i < a.size(); i++ ) { 20 | r = r && (a(i) == b(i)); 21 | } 22 | 23 | return r; 24 | } 25 | 26 | int main() { 27 | 28 | xt::xtensor_fixed> x, y; 29 | int i; 30 | bool r; 31 | 32 | for( i = 0; i < x.size(); i++ ) { 33 | x(i) = i; 34 | } 35 | 36 | copy_from_to(x, y); 37 | std::cout<< x << std::endl; 38 | std::cout << y << std::endl; 39 | r = verify(x, y); 40 | std::cout << r << std::endl; 41 | if (!r) { 42 | exit(2); 43 | } 44 | 45 | return 0; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /integration_tests/array_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | 7 | int main() { 8 | 9 | xt::xtensor_fixed> nums_int = {5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5}; 10 | xt::xtensor_fixed> nums_real = {1.5, -3.2, 4.5, 0.9, 7.2}; 11 | 12 | if (xt::amin(nums_int)() != -5) { 13 | exit(2); 14 | } 15 | if (xt::amax(nums_int)() != 5) { 16 | exit(2); 17 | } 18 | if (xt::amin(nums_real)() != -3.2) { 19 | exit(2); 20 | } 21 | if (xt::amax(nums_real)() != 7.2) { 22 | exit(2); 23 | } 24 | 25 | std::cout << xt::amin(nums_int)() << " " << xt::amax(nums_int)() << std::endl; 26 | std::cout << xt::amin(nums_real)() << " " << xt::amax(nums_real)() << std::endl; 27 | 28 | return 0; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /integration_tests/array_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | #include "xtensor/xview.hpp" 7 | 8 | double mysum(const int n, const xt::xtensor& A) { 9 | int i; 10 | double r = 0; 11 | for( i = 0; i < A.size(); i++ ) { 12 | r = r + A(i); 13 | } 14 | return r; 15 | } 16 | 17 | int main() { 18 | 19 | xt::xtensor B = xt::empty({10, 2}); 20 | double rescol1, rescol2; 21 | 22 | xt::view(B, xt::all(), 0) = 1; 23 | xt::view(B, xt::all(), 1) = 2; 24 | 25 | rescol1 = mysum(B.shape(0), xt::view(B, xt::all(), 0)); 26 | std::cout << rescol1 << std::endl; 27 | if( rescol1 != 10.0 ) { 28 | exit(2); 29 | } 30 | 31 | rescol2 = mysum(B.shape(1), xt::view(B, xt::all(), 1)); 32 | std::cout << rescol2 << std::endl; 33 | if( mysum(B.shape(0), xt::view(B, xt::all(), 1)) != 20.0 ) { 34 | exit(2); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /integration_tests/array_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "xtensor/xio.hpp" 5 | 6 | void f(xt::xtensor& a, int n, 7 | xt::xtensor& x, int i) { 8 | x(i) = i; 9 | a(i) = 2 * i; 10 | if (i + 1 < n) { 11 | f(a, n, x, i + 1); 12 | } 13 | } 14 | 15 | int main() { 16 | 17 | xt::xtensor y = xt::empty({20}); 18 | xt::xtensor a = xt::empty({20}); 19 | int i; 20 | 21 | f(a, 20, y, 0); 22 | 23 | std::cout << y << std::endl; 24 | std::cout << a << std::endl; 25 | 26 | for( int i = 0; i < 20; i++ ) { 27 | if (2 * y(i) != a(i)) { 28 | exit(2); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /integration_tests/array_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "xtensor/xio.hpp" 5 | 6 | xt::xtensor copy_array(const xt::xtensor& input); 7 | xt::xtensor twice(const xt::xtensor& x); 8 | 9 | xt::xtensor prg(const xt::xtensor& arr) { 10 | xt::xtensor otpt = xt::xtensor({arr.shape(0), arr.shape(1)}); 11 | otpt = copy_array(twice(copy_array(arr))); 12 | return otpt; 13 | } 14 | 15 | xt::xtensor twice(const xt::xtensor& x) { 16 | xt::xtensor y = xt::empty({x.shape(0), x.shape(1)}); 17 | y = 2.0*x; 18 | return y; 19 | } 20 | 21 | xt::xtensor copy_array(const xt::xtensor& input) { 22 | xt::xtensor output = xt::empty({input.shape(0), input.shape(1)}); 23 | output = input; 24 | return output; 25 | } 26 | 27 | int main() { 28 | 29 | xt::xtensor array = xt::empty({10, 10}); 30 | xt::xtensor output = xt::empty({10, 10}); 31 | 32 | array.fill(3.0); 33 | 34 | output = prg(array); 35 | std::cout << output << std::endl; 36 | if( xt::any(xt::not_equal(output, 6.0)) ) { 37 | exit(2); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /integration_tests/array_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "xtensor/xio.hpp" 6 | 7 | void fill_array(xt::xtensor& aa); 8 | 9 | int main() { 10 | xt::xtensor a = xt::empty({10}); 11 | xt::xtensor_fixed> ae = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 12 | 13 | fill_array(a); 14 | std::cout << a << std::endl; 15 | if( xt::any(xt::not_equal(a, ae)) ) { 16 | exit(2); 17 | } 18 | } 19 | 20 | void fill_array(xt::xtensor& a) { 21 | int i; 22 | for( i = 0; i < 10; i++ ) { 23 | a[i] = i; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /integration_tests/enum_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum Color { 4 | RED = 1, 5 | GREEN = 2, 6 | BLUE = 3 7 | }; 8 | 9 | void test_color_enum() { 10 | std::cout << RED << " " << GREEN << " " << BLUE << std::endl; 11 | if( RED != 1 ) { 12 | exit(2); 13 | } 14 | if( GREEN != 2 ) { 15 | exit(2); 16 | } 17 | if( BLUE != 3 ) { 18 | exit(2); 19 | } 20 | } 21 | 22 | void test_selected_color(enum Color selected_color) { 23 | enum Color color; 24 | color = selected_color; 25 | if( color != RED ) { 26 | exit(2); 27 | } 28 | std::cout << color << std::endl; 29 | } 30 | 31 | int main() { 32 | 33 | test_color_enum(); 34 | test_selected_color(RED); 35 | 36 | return 0; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /integration_tests/enum_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum MolecularMass { 4 | water = 18, 5 | methane = 16, 6 | ammonia = 17, 7 | oxygen = 16 8 | }; 9 | 10 | enum RelativeCharge { 11 | proton = 1, 12 | electron = -1, 13 | neutron = 0 14 | }; 15 | 16 | void test_mm() { 17 | std::cout << methane << " " << oxygen << std::endl; 18 | if( methane != oxygen ) { 19 | exit(2); 20 | } 21 | 22 | std::cout << ammonia - methane << std::endl; 23 | if( ammonia - methane != 1 ) { 24 | exit(2); 25 | } 26 | 27 | std::cout << water << " " << oxygen + 2 << std::endl; 28 | if( water != oxygen + 2 ) { 29 | exit(2); 30 | } 31 | } 32 | 33 | void test_rc() { 34 | std::cout << proton << " " << electron << " " << neutron << std::endl; 35 | if( proton + electron != neutron ) { 36 | exit(2); 37 | } 38 | } 39 | 40 | int main() { 41 | 42 | test_mm(); 43 | test_rc(); 44 | 45 | return 0; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /integration_tests/enum_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum Color { 4 | RED, 5 | GREEN, 6 | BLUE = 7, 7 | YELLOW, 8 | WHITE, 9 | PINK = 15, 10 | GREY 11 | }; 12 | 13 | enum Integers { 14 | a = -5, 15 | b, 16 | c, 17 | d = 0, 18 | e, 19 | f = 7, 20 | g 21 | }; 22 | 23 | void assert(bool condition) { 24 | if( !condition ) { 25 | exit(2); 26 | } 27 | } 28 | 29 | void test_color_enum() { 30 | std::cout << RED << std::endl; 31 | std::cout << GREEN << std::endl; 32 | std::cout << BLUE << std::endl; 33 | std::cout << YELLOW << std::endl; 34 | std::cout << WHITE << std::endl; 35 | std::cout << PINK << std::endl; 36 | std::cout << GREY << std::endl; 37 | 38 | assert( RED == 0 ); 39 | assert( GREEN == 1 ); 40 | assert( BLUE == 7 ); 41 | assert( YELLOW == 8 ); 42 | assert( WHITE == 9 ); 43 | assert( PINK == 15 ); 44 | assert( GREY == 16 ); 45 | } 46 | 47 | void test_selected_color(enum Color selected_color) { 48 | enum Color color; 49 | color = selected_color; 50 | assert( color == YELLOW); 51 | std::cout << color << std::endl; 52 | } 53 | 54 | void test_integer(enum Integers integer, int value) { 55 | assert(integer == value); 56 | } 57 | 58 | void test_integers() { 59 | std::cout << a << std::endl; 60 | test_integer(a, -5); 61 | 62 | std::cout << b << std::endl; 63 | test_integer(b, -4); 64 | 65 | std::cout << c << std::endl; 66 | test_integer(c, -3); 67 | 68 | std::cout << d << std::endl; 69 | test_integer(d, 0); 70 | 71 | std::cout << e << std::endl; 72 | test_integer(e, 1); 73 | 74 | std::cout << f << std::endl; 75 | test_integer(f, 7); 76 | 77 | std::cout << g << std::endl; 78 | test_integer(g, 8); 79 | } 80 | 81 | int main() { 82 | 83 | test_color_enum(); 84 | test_selected_color(YELLOW); 85 | test_integers(); 86 | 87 | } 88 | -------------------------------------------------------------------------------- /integration_tests/enum_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | enum Color { 5 | RED, 6 | GREEN, 7 | BLUE, 8 | PINK, 9 | WHITE, 10 | YELLOW 11 | }; 12 | 13 | struct Truck_t { 14 | float horsepower; 15 | int32_t seats; 16 | double price; 17 | enum Color color; 18 | }; 19 | 20 | void init_Truck(Truck_t& truck, float horsepower_, int32_t seats_, double price_, enum Color color_) { 21 | truck.horsepower = horsepower_; 22 | truck.seats = seats_; 23 | truck.price = price_; 24 | truck.color = color_; 25 | } 26 | 27 | void print_Truck(const Truck_t& car) { 28 | std::cout << car.horsepower << " " << car.seats << " " << car.price << " " << car.color << std::endl; 29 | } 30 | 31 | void assert_(bool condition) { 32 | if( !condition ) { 33 | exit(2); 34 | } 35 | } 36 | 37 | void test_enum_as_struct_member() { 38 | xt::xtensor_fixed> cars; 39 | init_Truck(cars(0), 700.0, 4, 100000.0, RED); 40 | init_Truck(cars(1), 800.0, 5, 200000.0, BLUE); 41 | init_Truck(cars(2), 400.0, 4, 50000.0, WHITE); 42 | print_Truck(cars(0)); 43 | print_Truck(cars(1)); 44 | print_Truck(cars(2)); 45 | assert_( cars(2).color == WHITE ); 46 | assert_( cars(1).color == BLUE ); 47 | assert_( cars(0).color == RED ); 48 | } 49 | 50 | int main() { 51 | 52 | test_enum_as_struct_member(); 53 | 54 | return 0; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /integration_tests/expr1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int x; 5 | x = (2+3)*5; 6 | printf("%d\n", x); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /integration_tests/expr2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void subrout(int x) { 4 | printf("%s %d\n", "x is", x); 5 | } 6 | 7 | int func(int x) { 8 | return x + 2; 9 | } 10 | 11 | int main() { 12 | int p = 26; 13 | subrout(p); 14 | p = func(p); 15 | printf("%s %d\n", "p is", p); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /integration_tests/expr3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | int x; 6 | x = (2+3)*5; 7 | exit(1); 8 | printf("%d\n", x); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /integration_tests/function_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float f_real(const float); 4 | 5 | float f(const float a) { 6 | float b, x; 7 | x = 2; 8 | b = a + f_real(0.0); 9 | return b; 10 | } 11 | 12 | float f_real(const float a) { 13 | float b; 14 | if( a == 0.0 ) { 15 | b = 2.0; 16 | } else { 17 | b = a + f(1.0); 18 | } 19 | return b; 20 | } 21 | 22 | int main() { 23 | 24 | float x = 5, y; 25 | float p = 5, q; 26 | float a, b, c; 27 | y = f(x); 28 | std::cout << y << std::endl; 29 | if( y != 7.0 ) { 30 | exit(2); 31 | } 32 | 33 | q = f_real(p); 34 | std::cout << q << std::endl; 35 | if( q != 8.0 ) { 36 | exit(2); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /integration_tests/lnn/utils/utils_main.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double normalize(double value, double leftMin, double leftMax, double rightMin, double rightMax) { 4 | // Figure out how 'wide' each range is 5 | double leftSpan = leftMax - leftMin; 6 | double rightSpan = rightMax - rightMin; 7 | 8 | // Convert the left range into a 0-1 range (float) 9 | double valueScaled = (value - leftMin) / leftSpan; 10 | 11 | // Convert the 0-1 range into a value in the right range. 12 | return rightMin + (valueScaled * rightSpan); 13 | } 14 | 15 | void normalize_input_vectors(std::vector>& input_vectors) { 16 | int32_t rows = input_vectors.size(); 17 | int32_t cols = input_vectors[0].size(); 18 | 19 | int32_t j; 20 | for( j = 0; j < cols; j++ ) { 21 | double colMinVal = input_vectors[0][j]; 22 | double colMaxVal = input_vectors[0][j]; 23 | int32_t i; 24 | for( i = 0; i < rows; i++ ) { 25 | if( input_vectors[i][j] > colMaxVal ) { 26 | colMaxVal = input_vectors[i][j]; 27 | } 28 | if( input_vectors[i][j] < colMinVal ) { 29 | colMinVal = input_vectors[i][j]; 30 | } 31 | } 32 | 33 | for( i = 0; i < rows; i++ ) { 34 | input_vectors[i][j] = normalize(input_vectors[i][j], colMinVal, colMaxVal, -1.0, 1.0); 35 | } 36 | } 37 | } 38 | 39 | void normalize_output_vector(std::vector& output_vector) { 40 | int32_t rows = output_vector.size(); 41 | double colMinVal = output_vector[0]; 42 | double colMaxVal = output_vector[0]; 43 | int32_t i; 44 | for( i = 0; i < rows; i++ ) { 45 | if( output_vector[i] > colMaxVal ) { 46 | colMaxVal = output_vector[i]; 47 | } 48 | if( output_vector[i] < colMinVal ) { 49 | colMinVal = output_vector[i]; 50 | } 51 | } 52 | 53 | for( i = 0; i < rows; i++ ) { 54 | output_vector[i] = normalize(output_vector[i], colMinVal, colMaxVal, -1.0, 1.0); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /integration_tests/loop_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define assert(cond) if( !(cond) ) { \ 4 | exit(2); \ 5 | } \ 6 | 7 | void test_loop_01() { 8 | int32_t i = 0; 9 | int32_t j = 0; 10 | 11 | while( false ) { 12 | assert( false ); 13 | } 14 | 15 | while( i < 0 ) { 16 | assert( false ); 17 | } 18 | 19 | while( i < 10 ) { 20 | i += 1; 21 | } 22 | std::cout< 0; i-- ) { 47 | j = j + i; 48 | } 49 | std::cout< 2 | #include 3 | 4 | void Pixel(int32_t H, int32_t W, xt::xtensor& Screen, int32_t x, int32_t y) { 5 | if( x >= 0 and y >= 0 and x < W and y < H ) { 6 | Screen(H - 1 - y, x) = 255; 7 | } 8 | } 9 | 10 | void Clear(int32_t H, int32_t W, xt::xtensor& Screen) { 11 | int32_t i; 12 | int32_t j; 13 | for( i = 0; i < H; i++ ) { 14 | for( j = 0; j < W; j++ ) { 15 | Screen(i, j) = 0; 16 | } 17 | } 18 | } 19 | 20 | void DisplayTerminal(int32_t H, int32_t W, xt::xtensor& Screen) { 21 | int32_t i, j; 22 | 23 | std::cout<<"+"; 24 | for( i = 0; i < W; i++ ) { 25 | std::cout<<"-"; 26 | } 27 | std::cout<<"+\n"; 28 | 29 | for( i = 0; i < H; i++ ) { 30 | std::cout<<"|"; 31 | for( j = 0; j < W; j++ ) { 32 | if( bool(Screen(i, j)) ) { 33 | std::cout<<"."; 34 | } else { 35 | std::cout<<" "; 36 | } 37 | } 38 | std::cout<<"|"; 39 | } 40 | 41 | std::cout<<"+"; 42 | for( i = 0; i < W; i++ ) { 43 | std::cout<<"-"; 44 | } 45 | std::cout<<"+"; 46 | } 47 | 48 | void Display(int32_t H, int32_t W, xt::xtensor& Screen) { 49 | int32_t i, j; 50 | 51 | std::cout<<"P2"; 52 | std::cout<& Screen, int32_t x1, int32_t y1, int32_t x2, int32_t y2) { 63 | int32_t dx = abs(x2 - x1); 64 | int32_t dy = abs(y2 - y1); 65 | 66 | int32_t sx, sy; 67 | 68 | if( x1 < x2 ) { 69 | sx = 1; 70 | } else { 71 | sx = -1; 72 | } 73 | 74 | if( y1 < y2 ) { 75 | sy = 1; 76 | } else { 77 | sy = -1; 78 | } 79 | 80 | int32_t err = dx - dy; 81 | 82 | while( x1 != x2 or y1 != y2 ) { 83 | Pixel(H, W, Screen, x1, y1); 84 | int32_t e2 = 2 * err; 85 | 86 | if( e2 > -dy ) { 87 | err -= dy; 88 | x1 += sx; 89 | } 90 | 91 | if( x1 == x2 and y1 == y2 ) { 92 | Pixel(H, W, Screen, x1, y1); 93 | break; 94 | } 95 | 96 | if( e2 < dx ) { 97 | err += dx; 98 | y1 += sy; 99 | } 100 | } 101 | } 102 | 103 | void Circle(int32_t H, int32_t W, xt::xtensor& Screen, int32_t x, int32_t y, double r) { 104 | int32_t x0 = r; 105 | int32_t y0 = 0; 106 | int32_t err = 0; 107 | 108 | while( x0 >= y0 ) { 109 | Pixel(H, W, Screen, x + x0, y + y0); 110 | Pixel(H, W, Screen, x - x0, y + y0); 111 | Pixel(H, W, Screen, x + x0, y - y0); 112 | Pixel(H, W, Screen, x - x0, y - y0); 113 | Pixel(H, W, Screen, x + y0, y + x0); 114 | Pixel(H, W, Screen, x - y0, y + x0); 115 | Pixel(H, W, Screen, x + y0, y - x0); 116 | Pixel(H, W, Screen, x - y0, y - x0); 117 | 118 | if( err <= 0 ) { 119 | y0 += 1; 120 | err += 2 * y0 + 1; 121 | } 122 | if( err > 0 ) { 123 | x0 -= 1; 124 | err -= 2 * x0 + 1; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /integration_tests/pointer_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std::complex_literals; 5 | 6 | #define check(p, t, v) if( *p != v ) { \ 7 | exit(2); \ 8 | } \ 9 | if( t != v ) { \ 10 | exit(2); \ 11 | } \ 12 | 13 | int main() { 14 | 15 | int* p1; 16 | double* p2; 17 | int t1 = 2; 18 | double t2 = 2.0; 19 | std::complex* p3; 20 | std::complex t3 = 2.0 + 1i*3.0; 21 | 22 | p1 = &t1; 23 | p2 = &t2; 24 | p3 = &t3; 25 | *p1 = 1; 26 | *p2 = 4.0; 27 | 28 | std::cout << *p1 << std::endl; 29 | std::cout << t1 << std::endl; 30 | check(p1, t1, 1) 31 | 32 | t1 = *p2 + *p1; 33 | 34 | std::cout << *p1 << std::endl; 35 | std::cout << t1 << std::endl; 36 | check(p1, t1, 5); 37 | 38 | t1 = 8; 39 | 40 | std::cout << *p1 << std::endl; 41 | std::cout << t1 << std::endl; 42 | check(p1, t1, 8); 43 | 44 | *p3 = 2.0 * (*p3); 45 | std::cout << *p3 << std::endl; 46 | std::cout << t3 << std::endl; 47 | check(p3, t3, 4.0 + 1i*6.0); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /integration_tests/pointer_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int* p1; 6 | int t1 = 2, t2 = 1; 7 | int i; 8 | 9 | std::cout << t1 << t2 << std::endl; 10 | 11 | if (t1 > t2) { 12 | p1 = &t1; 13 | } else { 14 | p1 = &t2; 15 | } 16 | 17 | std::cout << *p1 << std::endl; 18 | 19 | if (*p1 == t2) { 20 | exit(2); 21 | } 22 | 23 | i = *p1; 24 | if (i == t2) { 25 | exit(2); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /integration_tests/pointer_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | float myreal, x, y, theta, a; 7 | x = 0.42; 8 | y = 0.35; 9 | myreal = 9.1; 10 | theta = 1.5; 11 | a = 0.4; 12 | 13 | { 14 | #define z -(x*2 + y*2) * cos(theta) 15 | float v; // TODO: Convert to float* later 16 | v = myreal; 17 | std::cout << a + z << " " << a - z << " " << v << std::endl; 18 | v = v * 4.6; 19 | myreal = v; 20 | } 21 | 22 | std::cout << myreal << std::endl; 23 | 24 | if (abs(myreal - 41.86) > 1e-5) { 25 | exit(2); 26 | } 27 | 28 | return 0; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /integration_tests/pytorch_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void check(const torch::Tensor& tensor=torch::empty({1})) { 5 | float array[5] = {4.0, 2.0, 2.0, 12.0, 2.0}; 6 | std::cout << tensor << "\n"; 7 | if( torch::any(torch::abs(tensor - torch::from_blob(array, {5})) > 1e-8).item() ) { 8 | exit(2); 9 | } 10 | } 11 | 12 | int main() { 13 | torch::Tensor tensor = torch::ones(5); 14 | tensor[0] = 2.0; 15 | tensor[3] = 6.0; 16 | tensor = 2 * tensor; 17 | check(tensor); 18 | std::cout << tensor << "\n"; 19 | } 20 | -------------------------------------------------------------------------------- /integration_tests/struct_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std::complex_literals; 5 | 6 | // module derived_types_01_m_01 7 | struct X { 8 | float r; 9 | int i; 10 | }; 11 | 12 | struct Y { 13 | std::complex c; 14 | struct X d; 15 | }; 16 | 17 | void set(struct X& a) { 18 | a.i = 1; 19 | a.r = 1.5; 20 | } 21 | // module derived_types_01_m_01 22 | 23 | // module derived_types_01_m_02 24 | struct Z { 25 | std::complex k; 26 | struct Y l; 27 | }; 28 | // module derived_types_01_m_02 29 | 30 | int main() { 31 | 32 | struct X b; 33 | struct Z c; 34 | 35 | b.i = 5; 36 | b.r = 3.5; 37 | std::cout << b.i << " " << b.r << std::endl; 38 | if( b.i != 5 ) { 39 | exit(2); 40 | } 41 | if( b.r != 3.5 ) { 42 | exit(2); 43 | } 44 | 45 | set(b); 46 | std::cout << b.i << " " << b.r << std::endl; 47 | if( b.i != 1 ) { 48 | exit(2); 49 | } 50 | if( b.r != 1.5 ) { 51 | exit(2); 52 | } 53 | 54 | c.l.d.r = 2.0; 55 | c.l.d.i = 2; 56 | c.k = 2.0 + 2i; 57 | std::cout << c.l.d.r << " " << c.l.d.i << " " << c.k << std::endl; 58 | if( c.l.d.r != 2.0 ) { 59 | exit(2); 60 | } 61 | if( c.l.d.i != 2 ) { 62 | exit(2); 63 | } 64 | if( c.k != 2.0 + 2i ) { 65 | exit(2); 66 | } 67 | 68 | set(c.l.d); 69 | std::cout << c.l.d.r << " " << c.l.d.i << " " << c.k << std::endl; 70 | if( c.l.d.r != 1.5 ) { 71 | exit(2); 72 | } 73 | if( c.l.d.i != 1.0 ) { 74 | exit(2); 75 | } 76 | if( c.k != 2.0 + 2i ) { 77 | exit(2); 78 | } 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /integration_tests/struct_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "struct_02_m_01.h" 3 | #include "struct_02_m_02.h" 4 | 5 | using namespace std::complex_literals; 6 | 7 | int main() { 8 | 9 | struct X b; 10 | struct Z c; 11 | 12 | b.i = 5; 13 | b.r = 3.5; 14 | std::cout << b.i << " " << b.r << std::endl; 15 | if( b.i != 5 ) { 16 | exit(2); 17 | } 18 | if( b.r != 3.5 ) { 19 | exit(2); 20 | } 21 | 22 | set(b); 23 | std::cout << b.i << " " << b.r << std::endl; 24 | if( b.i != 1 ) { 25 | exit(2); 26 | } 27 | if( b.r != 1.5 ) { 28 | exit(2); 29 | } 30 | 31 | c.l.d.r = 2.0; 32 | c.l.d.i = 2; 33 | c.k = 2.0 + 2i; 34 | std::cout << c.l.d.r << " " << c.l.d.i << " " << c.k << std::endl; 35 | if( c.l.d.r != 2.0 ) { 36 | exit(2); 37 | } 38 | if( c.l.d.i != 2 ) { 39 | exit(2); 40 | } 41 | if( c.k != 2.0 + 2i ) { 42 | exit(2); 43 | } 44 | 45 | set(c.l.d); 46 | std::cout << c.l.d.r << " " << c.l.d.i << " " << c.k << std::endl; 47 | if( c.l.d.r != 1.5 ) { 48 | exit(2); 49 | } 50 | if( c.l.d.i != 1.0 ) { 51 | exit(2); 52 | } 53 | if( c.k != 2.0 + 2i ) { 54 | exit(2); 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /integration_tests/struct_02_m_01.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEGRATION_TESTS_STRUCT_02_M_01_H 2 | #define INTEGRATION_TESTS_STRUCT_02_M_01_H 3 | 4 | #include 5 | 6 | struct X { 7 | float r; 8 | int i; 9 | }; 10 | 11 | struct Y { 12 | std::complex c; 13 | struct X d; 14 | }; 15 | 16 | void set(struct X& a) { 17 | a.i = 1; 18 | a.r = 1.5; 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /integration_tests/struct_02_m_02.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEGRATION_TESTS_STRUCT_02_M_02_H 2 | #define INTEGRATION_TESTS_STRUCT_02_M_02_H 3 | 4 | #include "struct_02_m_01.h" 5 | 6 | struct Z { 7 | std::complex k; 8 | struct Y l; 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /integration_tests/struct_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "struct_03_m_01.h" 3 | 4 | int main() { 5 | struct t x; 6 | x = new_value(); 7 | std::cout << x.i << std::endl; 8 | if (x.i != 123) { 9 | exit(2); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /integration_tests/struct_03_m_01.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEGRATION_TESTS_STRUCT_03_M_01_H 2 | #define INTEGRATION_TESTS_STRUCT_03_M_01_H 3 | 4 | struct t { 5 | int i; 6 | }; 7 | 8 | struct t new_value() { 9 | struct t p; 10 | p.i = 123; 11 | return p; 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /integration_tests/struct_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "struct_04_m_01.h" 3 | 4 | void pass() { 5 | std::cout << struct_instance_sample.A << struct_instance_sample.B << std::endl; 6 | if (abs(struct_instance_sample.A - 10.0) > 1.0e-7) { 7 | exit(2); 8 | } 9 | if (abs(struct_instance_sample.B - 20.0) > 1.0e-7) { 10 | exit(2); 11 | } 12 | } 13 | 14 | int main() { 15 | struct_instance_sample.A = 10.0; 16 | struct_instance_sample.B = 20.0; 17 | pass(); 18 | } 19 | -------------------------------------------------------------------------------- /integration_tests/struct_04_m_01.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEGRATION_TESTS_STRUCT_04_M_01_H 2 | #define INTEGRATION_TESTS_STRUCT_04_M_01_H 3 | 4 | struct sample { 5 | float A, B, E; 6 | }; 7 | 8 | struct sample struct_instance_sample; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /integration_tests/struct_05.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A_t { 4 | float y; 5 | int32_t x; 6 | 7 | constexpr A_t(float y_, int32_t x_): y(y_), x(x_) {} 8 | }; 9 | 10 | void assert(bool condition) { 11 | if( !condition ) { 12 | exit(2); 13 | } 14 | } 15 | 16 | void f(const A_t& a) { 17 | std::cout << a.x << std::endl; 18 | std::cout << a.y << std::endl; 19 | } 20 | 21 | void change_struct(A_t& a) { 22 | a.x = a.x + 1; 23 | a.y = a.y + float(1); 24 | } 25 | 26 | void g() { 27 | A_t x = A_t(float(3.25), 3); 28 | f(x); 29 | assert( x.x == 3 ); 30 | assert( double(x.y) == 3.25 ); 31 | 32 | x.x = 5; 33 | x.y = float(5.5); 34 | f(x); 35 | assert( x.x == 5 ); 36 | assert( double(x.y) == 5.5 ); 37 | change_struct(x); 38 | assert( x.x == 6 ); 39 | assert( double(x.y) == 6.5 ); 40 | } 41 | 42 | int main() { 43 | 44 | g(); 45 | 46 | return 0; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /integration_tests/struct_06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A_t { 4 | float y; 5 | int32_t x; 6 | }; 7 | 8 | struct B_t { 9 | int32_t z; 10 | struct A_t a; 11 | }; 12 | 13 | void init_A_t(A_t& a, float y_, int32_t x_) { 14 | a.y = y_; 15 | a.x = x_; 16 | } 17 | 18 | void init_B_t(B_t& b, int32_t z_, struct A_t a_) { 19 | b.z = z_; 20 | b.a = a_; 21 | } 22 | 23 | void assert(bool condition) { 24 | if( !condition ) { 25 | exit(2); 26 | } 27 | } 28 | 29 | void f(const B_t& b) { 30 | std::cout << b.z << " " << b.a.x << " " << b.a.y << std::endl; 31 | assert( b.z == 1 ); 32 | assert( b.a.x == 2 ); 33 | assert( double(b.a.y) == 3.0 ); 34 | } 35 | 36 | void g() { 37 | struct A_t a1; 38 | struct A_t a2; 39 | struct B_t b; 40 | init_A_t(a1, float(1.0), 1); 41 | init_A_t(a2, float(2.0), 2); 42 | init_B_t(b, 1, a1); 43 | b.a = a2; 44 | b.z = 1; 45 | b.a.x = 2; 46 | b.a.y = float(3.0); 47 | assert( a1.x == 1 ); 48 | assert( double(a1.y) == 1.0 ); 49 | assert( a2.x == 2 ); 50 | assert( double(a2.y) == 2.0 ); 51 | f(b); 52 | } 53 | 54 | int main() { 55 | 56 | g(); 57 | 58 | return 0; 59 | 60 | } 61 | -------------------------------------------------------------------------------- /integration_tests/switch_case_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int switch_case_with_no_fall_through(int x) { 4 | int value; 5 | switch(x) { 6 | case 1: { 7 | value = 2*x; 8 | break; 9 | } 10 | case 2: { 11 | value = 3*x; 12 | break; 13 | } 14 | case 3: { 15 | value = 4*x; 16 | break; 17 | } 18 | case 4: { 19 | value = 5*x; 20 | break; 21 | } 22 | default: { 23 | value = 6*x; 24 | } 25 | } 26 | return value; 27 | } 28 | 29 | 30 | int main() { 31 | int value; 32 | value = switch_case_with_no_fall_through(1); 33 | std::cout< 2 | 3 | int switch_case_with_fall_through(int x) { 4 | int value = x; 5 | switch(x) { 6 | case 1: { 7 | value = 2*value; 8 | break; 9 | } 10 | case 2: { 11 | value = 3*value; 12 | } 13 | case 3: { 14 | value = 4*value; 15 | break; 16 | } 17 | case 4: { 18 | value = 5*value; 19 | } 20 | default: { 21 | value = 6*value; 22 | } 23 | } 24 | return value; 25 | } 26 | 27 | 28 | int main() { 29 | int value; 30 | value = switch_case_with_fall_through(1); 31 | std::cout< 2 | 3 | union u_type { 4 | int32_t integer32; 5 | float real32; 6 | double real64; 7 | int64_t integer64; 8 | }; 9 | 10 | #define assert(cond) if( !(cond) ) { \ 11 | exit(2); \ 12 | } \ 13 | 14 | void test_union() { 15 | union u_type unionobj; 16 | unionobj.integer32 = 1; 17 | std::cout << unionobj.integer32 << std::endl; 18 | assert( unionobj.integer32 == 1 ); 19 | 20 | unionobj.real32 = 2.0; 21 | std::cout << unionobj.real32 << std::endl; 22 | assert( abs(unionobj.real32 - 2.0) <= 1e-6 ); 23 | 24 | unionobj.real64 = 3.5; 25 | std::cout << unionobj.real64 << std::endl; 26 | assert( abs(unionobj.real64 - 3.5) <= 1e-12 ); 27 | 28 | unionobj.integer64 = 4; 29 | std::cout << unionobj.integer64 << std::endl; 30 | assert( unionobj.integer64 == 4 ); 31 | } 32 | 33 | int main() { 34 | 35 | test_union(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /integration_tests/union_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A_t { 4 | int32_t ax; 5 | double ay; 6 | }; 7 | 8 | void init_A_t(struct A_t& a, int32_t ax_, double ay_) { 9 | a.ax = ax_; 10 | a.ay = ay_; 11 | } 12 | 13 | struct B_t { 14 | int64_t bx; 15 | double by; 16 | }; 17 | 18 | void init_B_t(struct B_t& b, int64_t bx_, double by_) { 19 | b.bx = bx_; 20 | b.by = by_; 21 | } 22 | 23 | struct C_t { 24 | int64_t cx; 25 | double cy; 26 | double cz; 27 | }; 28 | 29 | void init_C_t(struct C_t& c, int64_t cx_, double cy_, double cz_) { 30 | c.cx = cx_; 31 | c.cy = cy_; 32 | c.cz = cz_; 33 | } 34 | 35 | union D_t { 36 | struct A_t a; 37 | struct B_t b; 38 | struct C_t c; 39 | }; 40 | 41 | #define assert(cond) if( !(cond) ) { \ 42 | exit(2); \ 43 | } \ 44 | 45 | void test_struct_union() { 46 | union D_t d; 47 | 48 | struct A_t aobj; 49 | struct B_t bobj; 50 | struct C_t cobj; 51 | 52 | init_A_t(aobj, 0, 1.0); 53 | init_B_t(bobj, int(2), 7.0); 54 | init_C_t(cobj, int(5), 13.0, 8.0); 55 | 56 | d.a = aobj; 57 | std::cout << d.a.ax << " " << d.a.ay << std::endl; 58 | assert( d.a.ax == 0 ); 59 | assert( abs(d.a.ay - 1.0) <= 1e-12 ); 60 | 61 | d.b = bobj; 62 | std::cout << d.b.bx << " " << d.b.by << std::endl; 63 | assert( d.b.bx == int(2) ); 64 | assert( abs(d.b.by - 7.0) <= 1e-12 ); 65 | 66 | d.c = cobj; 67 | std::cout << d.c.cx << " " << d.c.cy << " " << d.c.cz << std::endl; 68 | assert( d.c.cx == 5 ); 69 | assert( abs(d.c.cy - 13.0) <= 1e-12 ); 70 | assert( abs(d.c.cz - 8.0) <= 1e-12 ); 71 | } 72 | 73 | int main() { 74 | 75 | test_struct_union(); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /integration_tests/vector_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::vector fill_list_i32(int32_t size) { 5 | std::vector aarg = {0, 1, 2, 3, 4}; 6 | int32_t i; 7 | for( i = 0; i < size; i++) { 8 | aarg.push_back(i + 5); 9 | } 10 | return aarg; 11 | } 12 | 13 | #define assert(cond) if( !(cond) ) { \ 14 | exit(2); \ 15 | } \ 16 | 17 | void test_list_01() { 18 | std::vector a = {}; 19 | std::vector f = {1.0, 2.0, 3.0, 4.0, 5.0}; 20 | int32_t i; 21 | 22 | a = fill_list_i32(10); 23 | 24 | for( i = 0; i < 10; i++ ) { 25 | f.push_back(float(i + 6)); 26 | } 27 | 28 | for( i = 0; i < 15; i++ ) { 29 | std::cout << f[i] << std::endl; 30 | } 31 | 32 | for( i = 0; i < 15; i++ ) { 33 | assert( (f[i] - double(a[i])) == 1.0 ); 34 | } 35 | 36 | for( i = 0; i < 15; i++ ) { 37 | f[i] = f[i] + double(i); 38 | } 39 | 40 | for( i = 0; i < 15; i++ ) { 41 | assert( (f[i] - double(a[i])) == (double(i) + 1.0) ); 42 | } 43 | } 44 | 45 | 46 | void tests() { 47 | test_list_01(); 48 | } 49 | 50 | int main() { 51 | tests(); 52 | } 53 | -------------------------------------------------------------------------------- /integration_tests/vector_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define assert(cond) if( !(cond) ) { \ 5 | exit(2); \ 6 | } \ 7 | 8 | void check_mat_and_vec(std::vector>& mat, std::vector& vec) { 9 | int32_t rows = mat.size(); 10 | int32_t cols = vec.size(); 11 | int32_t i; 12 | int32_t j; 13 | 14 | for( i = 0; i < rows; i++ ) { 15 | for( j = 0; j < cols; j++ ) { 16 | assert( mat[i][j] == double(i + j) ); 17 | } 18 | } 19 | 20 | for( i = 0; i < cols; i++ ) { 21 | assert( vec[i] == 2.0 * float(i) ); 22 | } 23 | } 24 | 25 | void test_list_of_lists() { 26 | std::vector>>> arrays = {}; 27 | std::vector>> array = {}; 28 | std::vector> mat = {}; 29 | std::vector vec = {}; 30 | int32_t rows = 10; 31 | int32_t cols = 5; 32 | int32_t i; 33 | int32_t j; 34 | int32_t k; 35 | int32_t l; 36 | 37 | for( i = 0; i < rows; i++ ) { 38 | for( j = 0; j < cols; j++ ) { 39 | vec.push_back(double(i + j)); 40 | } 41 | mat.push_back(vec); 42 | vec.clear(); 43 | } 44 | 45 | for( i = 0; i < cols; i++ ) { 46 | vec.push_back(2.0 * double(i)); 47 | } 48 | 49 | check_mat_and_vec(mat, vec); 50 | 51 | for( k = 0; k < rows; k++ ) { 52 | array.push_back(mat); 53 | for( i = 0; i < rows; i++ ) { 54 | for( j = 0; j < cols; j++ ) { 55 | mat[i][j] += double(1); 56 | } 57 | } 58 | } 59 | 60 | for( k = 0; k < rows; k++ ) { 61 | for( i = 0; i < rows; i++ ) { 62 | for( j = 0; j < cols; j++ ) { 63 | assert( mat[i][j] - array[k][i][j] == double(rows - k) ); 64 | } 65 | } 66 | } 67 | 68 | for( l = 0; l < 2 * rows; l++ ) { 69 | arrays.push_back(array); 70 | for( i = 0; i < rows; i++ ) { 71 | for( j = 0; j < rows; j++ ) { 72 | for( k = 0; k < cols; k++ ) { 73 | array[i][j][k] += 1.0; 74 | } 75 | } 76 | } 77 | } 78 | 79 | for( l = 0; l < 2 * rows; l++ ) { 80 | for( i = 0; i < rows; i++ ) { 81 | for( j = 0; j < rows; j++ ) { 82 | for( k = 0; k < cols; k++ ) { 83 | std::cout << (array[i][j][k] - arrays[l][i][j][k]); 84 | std::cout << 2 * rows - l; 85 | assert( array[i][j][k] - arrays[l][i][j][k] == double(2 * rows - l) ); 86 | } 87 | } 88 | } 89 | } 90 | } 91 | 92 | int main() { 93 | 94 | test_list_of_lists(); 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(bin) 2 | add_subdirectory(lc) 3 | add_subdirectory(libasr) 4 | add_subdirectory(runtime/legacy) 5 | -------------------------------------------------------------------------------- /src/bin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(lc lc.cpp) 2 | target_include_directories(lc PRIVATE "tpl") 3 | target_link_libraries(lc p::clang p::llvm asr lc_lib) 4 | install(TARGETS lc DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) 5 | -------------------------------------------------------------------------------- /src/bin/tpl/whereami/whereami.h: -------------------------------------------------------------------------------- 1 | // (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses 2 | // without any warranty. 3 | // by Gregory Pakosz (@gpakosz) 4 | // https://github.com/gpakosz/whereami 5 | 6 | #ifndef WHEREAMI_H 7 | #define WHEREAMI_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #ifndef WAI_FUNCSPEC 14 | #define WAI_FUNCSPEC 15 | #endif 16 | #ifndef WAI_PREFIX 17 | #define WAI_PREFIX(function) wai_##function 18 | #endif 19 | 20 | /** 21 | * Returns the path to the current executable. 22 | * 23 | * Usage: 24 | * - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to 25 | * retrieve the length of the path 26 | * - allocate the destination buffer with `path = (char*)malloc(length + 1);` 27 | * - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the 28 | * path 29 | * - add a terminal NUL character with `path[length] = '\0';` 30 | * 31 | * @param out destination buffer, optional 32 | * @param capacity destination buffer capacity 33 | * @param dirname_length optional recipient for the length of the dirname part 34 | * of the path. 35 | * 36 | * @return the length of the executable path on success (without a terminal NUL 37 | * character), otherwise `-1` 38 | */ 39 | WAI_FUNCSPEC 40 | int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length); 41 | 42 | /** 43 | * Returns the path to the current module 44 | * 45 | * Usage: 46 | * - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve 47 | * the length of the path 48 | * - allocate the destination buffer with `path = (char*)malloc(length + 1);` 49 | * - call `wai_getModulePath(path, length, NULL)` again to retrieve the path 50 | * - add a terminal NUL character with `path[length] = '\0';` 51 | * 52 | * @param out destination buffer, optional 53 | * @param capacity destination buffer capacity 54 | * @param dirname_length optional recipient for the length of the dirname part 55 | * of the path. 56 | * 57 | * @return the length of the module path on success (without a terminal NUL 58 | * character), otherwise `-1` 59 | */ 60 | WAI_FUNCSPEC 61 | int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif // #ifndef WHEREAMI_H 68 | -------------------------------------------------------------------------------- /src/lc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SRC 2 | parser/tokenizer.cpp 3 | parser/parser.cpp 4 | parser/parser.tab.cc 5 | 6 | clang_ast_to_asr.cpp 7 | utils.cpp 8 | ) 9 | 10 | if (WITH_WHEREAMI) 11 | set(SRC ${SRC} ../bin/tpl/whereami/whereami.cpp) 12 | endif() 13 | 14 | add_library(lc_lib STATIC ${SRC}) 15 | target_link_libraries(lc_lib asr lc_runtime_static) 16 | 17 | target_include_directories(lc_lib BEFORE PUBLIC ${lfortran_SOURCE_DIR}/src) 18 | target_include_directories(lc_lib BEFORE PUBLIC ${lfortran_BINARY_DIR}/src) 19 | 20 | if (WITH_ZLIB) 21 | target_link_libraries(lc_lib ZLIB::ZLIB) 22 | endif() 23 | if (WITH_XEUS) 24 | target_link_libraries(lc_lib xeus xeus-zmq) 25 | endif() 26 | if (WITH_JSON) 27 | target_link_libraries(lc_lib p::rapidjson) 28 | endif() 29 | if (WITH_BFD) 30 | target_link_libraries(lc_lib p::bfd) 31 | endif() 32 | if (WITH_LINK) 33 | target_link_libraries(lc_lib p::link) 34 | endif() 35 | if (WITH_EXECINFO) 36 | target_link_libraries(lc_lib p::execinfo) 37 | endif() 38 | if (WITH_LLVM) 39 | target_link_libraries(lc_lib p::llvm) 40 | endif() 41 | #install(TARGETS lc_lib 42 | # RUNTIME DESTINATION bin 43 | # ARCHIVE DESTINATION lib 44 | # LIBRARY DESTINATION lib 45 | #) 46 | -------------------------------------------------------------------------------- /src/lc/clang_ast_to_asr.h: -------------------------------------------------------------------------------- 1 | #ifndef CLANG_AST_TO_ASR_H 2 | #define CLANG_AST_TO_ASR_H 3 | 4 | #include 5 | 6 | namespace LCompilers::LC { 7 | int dump_clang_ast(std::string infile, std::string ast_dump_file, 8 | std::string ast_dump_filter, bool ast_list, bool ast_print, 9 | bool show_clang_ast, bool parse_all_comments); 10 | 11 | int clang_ast_to_asr(Allocator &al, std::string infile, 12 | LCompilers::ASR::asr_t*& tu, bool parse_all_comments); 13 | } // namespace LCompilers::LC 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/lc/parser/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef LC_PARSER_PARSER_H 2 | #define LC_PARSER_PARSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace LCompilers::LC { 9 | 10 | class Parser 11 | { 12 | public: 13 | std::string inp; 14 | 15 | public: 16 | diag::Diagnostics &diag; 17 | Allocator &m_a; 18 | Tokenizer m_tokenizer; 19 | Vec result; 20 | Vec type_ignore; 21 | 22 | Parser(Allocator &al, diag::Diagnostics &diagnostics) 23 | : diag{diagnostics}, m_a{al} { 24 | result.reserve(al, 32); 25 | type_ignore.reserve(al, 4); 26 | } 27 | 28 | void parse(const std::string &input, uint32_t prev_loc); 29 | void handle_yyerror(const Location &loc, const std::string &msg); 30 | }; 31 | 32 | 33 | // Parses Python code to AST 34 | Result parse(Allocator &al, 35 | const std::string &s, uint32_t prev_loc, 36 | diag::Diagnostics &diagnostics); 37 | 38 | Result parse_python_file(Allocator &al, 39 | const std::string &runtime_library_dir, 40 | const std::string &infile, 41 | diag::Diagnostics &diagnostics, 42 | uint32_t prev_loc, bool new_parser); 43 | 44 | } // namespace LCompilers::LC 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/lc/parser/parser_exception.h: -------------------------------------------------------------------------------- 1 | #ifndef LC_PARSER_PARSER_EXCEPTION_H 2 | #define LC_PARSER_PARSER_EXCEPTION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers::LC { 8 | 9 | namespace parser_local { 10 | 11 | // Local exceptions that are used to terminate the tokenizer. 12 | 13 | class TokenizerError 14 | { 15 | public: 16 | diag::Diagnostic d; 17 | public: 18 | TokenizerError(const std::string &msg, const Location &loc) 19 | : d{diag::Diagnostic(msg, diag::Level::Error, diag::Stage::Tokenizer, { 20 | diag::Label("", {loc}) 21 | })} 22 | { } 23 | 24 | TokenizerError(const diag::Diagnostic &d) : d{d} { } 25 | }; 26 | 27 | class ParserError 28 | { 29 | public: 30 | diag::Diagnostic d; 31 | public: 32 | ParserError(const std::string &msg, const Location &loc) 33 | : d{diag::Diagnostic(msg, diag::Level::Error, diag::Stage::Parser, { 34 | diag::Label("", {loc}) 35 | })} 36 | { } 37 | 38 | ParserError(const std::string &msg) 39 | : d{diag::Diagnostic(msg, diag::Level::Error, diag::Stage::Parser)} 40 | { } 41 | }; 42 | 43 | 44 | } 45 | 46 | } 47 | 48 | 49 | #endif // LC_PARSER_PARSER_EXCEPTION_H 50 | -------------------------------------------------------------------------------- /src/lc/parser/parser_stype.h: -------------------------------------------------------------------------------- 1 | #ifndef LC_PARSER_STYPE_H 2 | #define LC_PARSER_STYPE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace LCompilers::LC { 11 | 12 | struct Key_Val { 13 | LC::AST::expr_t* key; 14 | LC::AST::expr_t* value; 15 | }; 16 | 17 | struct Args { 18 | LC::AST::arguments_t arguments; 19 | }; 20 | 21 | struct Arg { 22 | bool default_value; 23 | LC::AST::arg_t _arg; 24 | LC::AST::expr_t *defaults; 25 | }; 26 | 27 | struct Var_Kw { 28 | Vec vararg; 29 | Vec kwonlyargs; 30 | Vec kwarg; 31 | }; 32 | 33 | struct Args_ { 34 | Vec args; 35 | bool var_kw_val; 36 | Var_Kw *var_kw; 37 | }; 38 | 39 | struct Fn_Arg { 40 | Vec posonlyargs; 41 | bool args_val; 42 | Args_ *args; 43 | }; 44 | 45 | struct Kw_or_Star_Arg { 46 | LC::AST::expr_t *star_arg; 47 | LC::AST::keyword_t *kw_arg; 48 | }; 49 | 50 | struct Call_Arg { 51 | Vec expr; 52 | Vec kw; 53 | }; 54 | 55 | struct Key_Val_Pattern { 56 | LC::AST::expr_t* key; 57 | LC::AST::pattern_t* val; 58 | }; 59 | 60 | union YYSTYPE { 61 | int64_t n; 62 | double f; 63 | Str string; 64 | 65 | LC::AST::ast_t* ast; 66 | Vec vec_ast; 67 | 68 | LC::AST::alias_t* alias; 69 | Vec vec_alias; 70 | 71 | Arg *arg; 72 | Vec vec_arg; 73 | 74 | Args *args; 75 | Vec vec_args; 76 | 77 | Fn_Arg *fn_arg; 78 | Args_ *args_; 79 | Var_Kw *var_kw; 80 | 81 | Key_Val *key_val; 82 | Vec vec_key_val; 83 | 84 | LC::AST::withitem_t* withitem; 85 | Vec vec_withitem; 86 | 87 | LC::AST::keyword_t* keyword; 88 | Vec vec_keyword; 89 | 90 | Kw_or_Star_Arg* kw_or_star; 91 | Vec vec_kw_or_star; 92 | 93 | Call_Arg *call_arg; 94 | 95 | LC::AST::comprehension_t* comp; 96 | Vec vec_comp; 97 | 98 | LC::AST::operatorType operator_type; 99 | 100 | LC::AST::match_case_t* match_case; 101 | Vec vec_match_case; 102 | 103 | LC::AST::pattern_t* pattern; 104 | Vec vec_pattern; 105 | 106 | Key_Val_Pattern *kw_val_pattern; 107 | Vec vec_kw_val_pattern; 108 | }; 109 | 110 | static_assert(std::is_standard_layout::value); 111 | static_assert(std::is_trivial::value); 112 | // Ensure the YYSTYPE size is equal to Vec, which is a required member, so 113 | // YYSTYPE must be at least as big, but it should not be bigger, otherwise it 114 | // would reduce performance. 115 | // A temporary fix for PowerPC 32-bit, where the following assert fails with (16 == 12). 116 | #ifndef __ppc__ 117 | static_assert(sizeof(YYSTYPE) == sizeof(Vec)); 118 | #endif 119 | 120 | static_assert(std::is_standard_layout::value); 121 | static_assert(std::is_trivial::value); 122 | 123 | } // namespace LCompilers::LC 124 | 125 | 126 | typedef struct LCompilers::Location YYLTYPE; 127 | #define YYLTYPE_IS_DECLARED 1 128 | #define YYLTYPE_IS_TRIVIAL 0 129 | #define YYINITDEPTH 2000 130 | 131 | 132 | #endif // LC_PARSER_STYPE_H 133 | -------------------------------------------------------------------------------- /src/lc/parser/tokenizer.h: -------------------------------------------------------------------------------- 1 | #ifndef LC_SRC_PARSER_TOKENIZER_H 2 | #define LC_SRC_PARSER_TOKENIZER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define MAX_PAREN_LEVEL 200 9 | 10 | namespace LCompilers::LC { 11 | 12 | class Tokenizer 13 | { 14 | public: 15 | unsigned char *cur; 16 | unsigned char *tok; 17 | unsigned char *cur_line; 18 | unsigned int line_num; 19 | unsigned char *string_start; 20 | uint32_t prev_loc; // The previous file ended at this location. 21 | 22 | int last_token=-1; 23 | 24 | bool indent = false; // Next line is expected to be indented 25 | int dedent = 0; // Allowed values: 0, 1, 2, see the code below the meaning of this state variable 26 | bool colon_actual_last_token = false; // If the actual last token was a colon 27 | long int last_indent_length = 0; 28 | unsigned char last_indent_type; 29 | std::vector indent_length; 30 | 31 | char paren_stack[MAX_PAREN_LEVEL]; 32 | size_t parenlevel = 0; 33 | 34 | public: 35 | // Set the string to tokenize. The caller must ensure `str` will stay valid 36 | // as long as `lex` is being called. 37 | void set_string(const std::string &str, uint32_t prev_loc_); 38 | 39 | // Get next token. Token ID is returned as function result, the semantic 40 | // value is put into `yylval`. 41 | int lex(Allocator &al, YYSTYPE &yylval, Location &loc, diag::Diagnostics &diagnostics); 42 | 43 | // Return the current token as std::string 44 | std::string token() const 45 | { 46 | return std::string((char *)tok, cur - tok); 47 | } 48 | 49 | // Return the current token as YYSTYPE::Str 50 | void token(Str &s) const 51 | { 52 | s.p = (char*) tok; 53 | s.n = cur-tok; 54 | } 55 | 56 | // Return the current token as YYSTYPE::Str, strips first and last character 57 | void token_str(Str &s) const 58 | { 59 | s.p = (char*) tok + 1; 60 | s.n = cur-tok-2; 61 | } 62 | 63 | // Return the current token as YYSTYPE::Str, strips the first 3 and the last 64 | // 3 characters 65 | void token_str3(Str &s) const 66 | { 67 | s.p = (char*) tok + 3; 68 | s.n = cur-tok-6; 69 | } 70 | 71 | // Return the current token's location 72 | void token_loc(Location &loc) const 73 | { 74 | loc.first = prev_loc + (tok-string_start); 75 | loc.last = prev_loc + (cur-string_start-1); 76 | } 77 | 78 | void record_paren(Location &loc, char c); 79 | 80 | void lex_match_or_case(Location &loc, unsigned char *cur, 81 | bool &is_match_or_case_keyword); 82 | }; 83 | 84 | std::string token2text(const int token); 85 | 86 | // Tokenizes the `input` and return a list of tokens 87 | Result> tokens(Allocator &al, const std::string &input, 88 | diag::Diagnostics &diagnostics, 89 | std::vector *stypes=nullptr, 90 | std::vector *locations=nullptr); 91 | 92 | std::string pickle_token(int token, const YYSTYPE &yystype); 93 | 94 | 95 | } // namespace LCompilers::LC 96 | 97 | #endif // LC_SRC_PARSER_TOKENIZER_H 98 | -------------------------------------------------------------------------------- /src/lc/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef LC_UTILS_H 2 | #define LC_UTILS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers::LC { 8 | 9 | void get_executable_path(std::string &executable_path, int &dirname_length); 10 | std::string get_runtime_library_dir(); 11 | std::string get_runtime_library_header_dir(); 12 | std::string get_runtime_library_c_header_dir(); 13 | std::string get_kokkos_dir(); 14 | int32_t get_exit_status(int32_t err); 15 | 16 | } // LCompilers::LC 17 | 18 | #endif // LC_UTILS_H 19 | -------------------------------------------------------------------------------- /src/libasr/asr_scopes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | std::string lcompilers_unique_ID; 8 | 9 | namespace LCompilers { 10 | 11 | template< typename T > 12 | std::string hexify(T i) 13 | { 14 | std::stringbuf buf; 15 | std::ostream os(&buf); 16 | os << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << i; 17 | return buf.str(); 18 | } 19 | 20 | unsigned int symbol_table_counter = 0; 21 | 22 | SymbolTable::SymbolTable(SymbolTable *parent) : parent{parent} { 23 | symbol_table_counter++; 24 | counter = symbol_table_counter; 25 | } 26 | 27 | void SymbolTable::reset_global_counter() { 28 | symbol_table_counter = 0; 29 | } 30 | 31 | void SymbolTable::mark_all_variables_external(Allocator &al) { 32 | for (auto &a : scope) { 33 | switch (a.second->type) { 34 | case (ASR::symbolType::Variable) : { 35 | ASR::Variable_t *v = ASR::down_cast(a.second); 36 | v->m_abi = ASR::abiType::Interactive; 37 | break; 38 | } 39 | case (ASR::symbolType::Function) : { 40 | ASR::Function_t *v = ASR::down_cast(a.second); 41 | ASR::FunctionType_t* v_func_type = ASR::down_cast(v->m_function_signature); 42 | v_func_type->m_abi = ASR::abiType::Interactive; 43 | v->m_body = nullptr; 44 | v->n_body = 0; 45 | break; 46 | } 47 | case (ASR::symbolType::Module) : { 48 | ASR::Module_t *v = ASR::down_cast(a.second); 49 | v->m_symtab->mark_all_variables_external(al); 50 | } 51 | default : {}; 52 | } 53 | } 54 | } 55 | 56 | ASR::symbol_t *SymbolTable::find_scoped_symbol(const std::string &name, 57 | size_t n_scope_names, char **m_scope_names) { 58 | const SymbolTable *s = this; 59 | for(size_t i=0; i < n_scope_names; i++) { 60 | std::string scope_name = m_scope_names[i]; 61 | if (s->scope.find(scope_name) != scope.end()) { 62 | ASR::symbol_t *sym = s->scope.at(scope_name); 63 | s = ASRUtils::symbol_symtab(sym); 64 | if (s == nullptr) { 65 | // The m_scope_names[i] found in the appropriate symbol table, 66 | // but points to a symbol that itself does not have a symbol 67 | // table 68 | return nullptr; 69 | } 70 | } else { 71 | // The m_scope_names[i] not found in the appropriate symbol table 72 | return nullptr; 73 | } 74 | } 75 | if (s->scope.find(name) != scope.end()) { 76 | ASR::symbol_t *sym = s->scope.at(name); 77 | LCOMPILERS_ASSERT(sym) 78 | return sym; 79 | } else { 80 | // The `name` not found in the appropriate symbol table 81 | return nullptr; 82 | } 83 | } 84 | 85 | std::string SymbolTable::get_unique_name(const std::string &name, bool use_unique_id) { 86 | std::string unique_name = name; 87 | if( use_unique_id && !lcompilers_unique_ID.empty()) { 88 | unique_name += "_" + lcompilers_unique_ID; 89 | } 90 | int counter = 1; 91 | while (scope.find(unique_name) != scope.end()) { 92 | unique_name = name + std::to_string(counter); 93 | counter++; 94 | } 95 | return unique_name; 96 | } 97 | 98 | } // namespace LCompilers 99 | -------------------------------------------------------------------------------- /src/libasr/asr_verify.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_VERIFY_H 2 | #define LFORTRAN_ASR_VERIFY_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | // Verifies that ASR is correctly constructed and contains valid Fortran 9 | // code and passes all our requirements on ASR, such as: 10 | // 11 | // * All types and kinds are correctly inferred and implicit casting 12 | // nodes are correctly inserted in expressions 13 | // * Types match for function / subroutine calls 14 | // * All symbols in the Symbol Table correctly link back to it or the 15 | // parent table. 16 | // * All Fortran rules will be checked eventually, such as: 17 | // * Initializer expression only uses intrinsic functions 18 | // * Any function used in array dimension declaration is pure 19 | // * Pure function only calls pure functions 20 | // * ... 21 | // 22 | // This should not replace correct semantic checking in ast2asr. This is 23 | // only meant as a tool for LCompilers developers to check there are no bugs 24 | // in LCompilers code that constructs ASR and that some requirement was not 25 | // accidentally broken. 26 | // This should not be called in Release mode for performance reasons, but 27 | // it should be called in our tests to ensure ast2asr, deserialization, all 28 | // the ASR passes and any other code that constructs ASR does not have 29 | // bugs. 30 | // Any code that takes ASR as an argument can assume that it is verified. 31 | // Such as the LLVM, C++ backend, or any ASR pass, or pickle. 32 | 33 | // The function will raise an exception if there is an error. Otherwise 34 | // it will return true. It can be used in Debug mode only as: 35 | // 36 | // LCOMPILERS_ASSERT(asr_verify(*asr)); 37 | // 38 | bool asr_verify(const ASR::TranslationUnit_t &unit, 39 | bool check_external, diag::Diagnostics &diagnostics); 40 | 41 | } // namespace LCompilers 42 | 43 | #endif // LFORTRAN_ASR_VERIFY_H 44 | -------------------------------------------------------------------------------- /src/libasr/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASSERT_H 2 | #define LFORTRAN_ASSERT_H 3 | 4 | // LCOMPILERS_ASSERT uses internal functions to perform as assert 5 | // so that there is no effect with NDEBUG 6 | #include 7 | #include 8 | #if defined(WITH_LFORTRAN_ASSERT) 9 | 10 | #include 11 | 12 | #if !defined(LCOMPILERS_ASSERT) 13 | #define stringize(s) #s 14 | #define XSTR(s) stringize(s) 15 | #if defined(HAVE_LFORTRAN_STACKTRACE) 16 | #define LCOMPILERS_ASSERT(cond) \ 17 | { \ 18 | if (!(cond)) { \ 19 | throw LCompilers::AssertFailed(XSTR(cond)); \ 20 | } \ 21 | } 22 | #else 23 | #define LCOMPILERS_ASSERT(cond) \ 24 | { \ 25 | if (!(cond)) { \ 26 | std::cerr << "LCOMPILERS_ASSERT failed: " << __FILE__ \ 27 | << "\nfunction " << __func__ << "(), line number " \ 28 | << __LINE__ << " at \n" \ 29 | << XSTR(cond) << "\n"; \ 30 | abort(); \ 31 | } \ 32 | } 33 | #endif // defined(HAVE_LFORTRAN_STACKTRACE) 34 | #endif // !defined(LCOMPILERS_ASSERT) 35 | 36 | #if !defined(LCOMPILERS_ASSERT_MSG) 37 | #define LCOMPILERS_ASSERT_MSG(cond, msg) \ 38 | { \ 39 | if (!(cond)) { \ 40 | std::cerr << "LCOMPILERS_ASSERT failed: " << __FILE__ \ 41 | << "\nfunction " << __func__ << "(), line number " \ 42 | << __LINE__ << " at \n" \ 43 | << XSTR(cond) << "\n" \ 44 | << "ERROR MESSAGE:\n" \ 45 | << msg << "\n"; \ 46 | abort(); \ 47 | } \ 48 | } 49 | #endif // !defined(LCOMPILERS_ASSERT_MSG) 50 | 51 | #else // defined(WITH_LFORTRAN_ASSERT) 52 | 53 | #define LCOMPILERS_ASSERT(cond) 54 | #define LCOMPILERS_ASSERT_MSG(cond, msg) 55 | 56 | #endif // defined(WITH_LFORTRAN_ASSERT) 57 | 58 | #define LFORTRAN_ERROR(description) \ 59 | std::cerr << description; \ 60 | std::cerr << "\n"; \ 61 | abort(); 62 | 63 | #endif // LFORTRAN_ASSERT_H 64 | -------------------------------------------------------------------------------- /src/libasr/casting_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_CASTING_UTILS_H 2 | #define LFORTRAN_CASTING_UTILS_H 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace LCompilers::CastingUtil { 10 | 11 | int get_type_priority(ASR::ttypeType type); 12 | 13 | int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr, 14 | ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr, 15 | ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type, 16 | bool is_assign, bool allow_int_to_float=false); 17 | 18 | ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* dest, 19 | Allocator& al, const Location& loc); 20 | } 21 | 22 | #endif // LFORTRAN_CASTING_UTILS_H 23 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_c.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_C_H 2 | #define LFORTRAN_ASR_TO_C_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, 10 | diag::Diagnostics &diagnostics, CompilerOptions &co, 11 | int64_t default_lower_bound); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_ASR_TO_C_H 16 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_cpp.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_CPP_H 2 | #define LFORTRAN_ASR_TO_CPP_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | Result asr_to_cpp(Allocator &al, ASR::TranslationUnit_t &asr, 10 | diag::Diagnostics &diagnostics, CompilerOptions &co, 11 | int64_t default_lower_bound); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_ASR_TO_CPP_H 16 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_fortran.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_FORTRAN_H 2 | #define LFORTRAN_ASR_TO_FORTRAN_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | // Converts ASR to Fortran source code 10 | Result asr_to_fortran(ASR::TranslationUnit_t &asr, 11 | diag::Diagnostics &diagnostics, bool color, int indent); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_ASR_TO_FORTRAN_H 16 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_julia.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_JULIA_H 2 | #define LFORTRAN_ASR_TO_JULIA_H 3 | 4 | #include 5 | #include 6 | #include 7 | // #include 8 | 9 | namespace LCompilers { 10 | 11 | Result 12 | asr_to_julia(Allocator& al, ASR::TranslationUnit_t& asr, diag::Diagnostics& diag); 13 | 14 | } // namespace LCompilers 15 | 16 | #endif // LFORTRAN_ASR_TO_JULIA_H 17 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_llvm.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_LLVM_H 2 | #define LFORTRAN_ASR_TO_LLVM_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace LCompilers { 9 | 10 | Result> asr_to_llvm(ASR::TranslationUnit_t &asr, 11 | diag::Diagnostics &diagnostics, 12 | llvm::LLVMContext &context, Allocator &al, 13 | LCompilers::PassManager& pass_manager, 14 | CompilerOptions &compiler_options, 15 | const std::string &run_fn, 16 | const std::string &infile); 17 | 18 | } // namespace LCompilers 19 | 20 | #endif // LFORTRAN_ASR_TO_LLVM_H 21 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_py.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_PY_H 2 | #define LFORTRAN_ASR_TO_PY_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | std::tuple asr_to_py(ASR::TranslationUnit_t &asr, bool c_order, std::string chdr_filename); 10 | 11 | } // namespace LCompilers 12 | 13 | #endif // LFORTRAN_ASR_TO_PY_H 14 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_python.h: -------------------------------------------------------------------------------- 1 | #ifndef LPYTHON_ASR_TO_PYTHON_H 2 | #define LPYTHON_ASR_TO_PYTHON_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | // Convert ASR to Python source code 10 | Result asr_to_python(Allocator &al, ASR::TranslationUnit_t &asr, 11 | diag::Diagnostics &diagnostics, CompilerOptions &co, 12 | bool color, int indent); 13 | 14 | } // namespace LCompilers 15 | 16 | #endif // LPYTHON_ASR_TO_PYTHON_H 17 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_wasm.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_WASM_H 2 | #define LFORTRAN_ASR_TO_WASM_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | // Generates a wasm binary stream from ASR 9 | Result> asr_to_wasm_bytes_stream(ASR::TranslationUnit_t &asr, 10 | Allocator &al, 11 | diag::Diagnostics &diagnostics, 12 | CompilerOptions &co); 13 | 14 | // Generates a wasm binary to `filename` 15 | Result asr_to_wasm(ASR::TranslationUnit_t &asr, Allocator &al, 16 | const std::string &filename, bool time_report, 17 | diag::Diagnostics &diagnostics, CompilerOptions &co); 18 | 19 | } // namespace LCompilers 20 | 21 | #endif // LFORTRAN_ASR_TO_WASM_H 22 | -------------------------------------------------------------------------------- /src/libasr/codegen/asr_to_x86.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_ASR_TO_X86_H 2 | #define LFORTRAN_ASR_TO_X86_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | // Generates a 32-bit x86 Linux executable binary `filename` 9 | Result asr_to_x86(ASR::TranslationUnit_t &asr, Allocator &al, 10 | const std::string &filename, bool time_report, 11 | diag::Diagnostics &diagnostics); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_ASR_TO_X86_H 16 | -------------------------------------------------------------------------------- /src/libasr/codegen/c_evaluator.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_EVALUATOR_H 2 | #define LFORTRAN_EVALUATOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // Forward declare all needed LLVM classes without importing any LLVM header 14 | // files. Those are only imported in evaluator.cpp and nowhere else, to speed 15 | // up compilation. 16 | namespace llvm { 17 | class ExecutionEngine; 18 | class LLVMContext; 19 | class Module; 20 | class Function; 21 | class TargetMachine; 22 | } 23 | 24 | namespace LCompilers { 25 | 26 | class LLVMModule 27 | { 28 | public: 29 | std::unique_ptr m_m; 30 | LLVMModule(std::unique_ptr m); 31 | ~LLVMModule(); 32 | std::string str(); 33 | // Return a function return type as a string (real / integer) 34 | std::string get_return_type(const std::string &fn_name); 35 | }; 36 | 37 | class LLVMEvaluator 38 | { 39 | private: 40 | std::unique_ptr context; 41 | std::string target_triple; 42 | llvm::TargetMachine *TM; 43 | public: 44 | LLVMEvaluator(const std::string &t = ""); 45 | ~LLVMEvaluator(); 46 | void save_object_file(llvm::Module &m, const std::string &filename); 47 | void opt(llvm::Module &m); 48 | static std::string module_to_string(llvm::Module &m); 49 | llvm::LLVMContext &get_context(); 50 | static std::string get_default_target_triple(); 51 | }; 52 | 53 | 54 | } // namespace LCompilers 55 | 56 | #endif // LFORTRAN_EVALUATOR_H 57 | -------------------------------------------------------------------------------- /src/libasr/codegen/evaluator.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_EVALUATOR_H 2 | #define LFORTRAN_EVALUATOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // Forward declare all needed LLVM classes without importing any LLVM header 14 | // files. Those are only imported in evaluator.cpp and nowhere else, to speed 15 | // up compilation. 16 | namespace llvm { 17 | class ExecutionEngine; 18 | class LLVMContext; 19 | class Module; 20 | class Function; 21 | class TargetMachine; 22 | namespace orc { 23 | class KaleidoscopeJIT; 24 | } 25 | } 26 | 27 | namespace LCompilers { 28 | 29 | class LLVMModule 30 | { 31 | public: 32 | std::unique_ptr m_m; 33 | LLVMModule(std::unique_ptr m); 34 | ~LLVMModule(); 35 | std::string str(); 36 | // Return a function return type as a string (real / integer) 37 | std::string get_return_type(const std::string &fn_name); 38 | }; 39 | 40 | class LLVMEvaluator 41 | { 42 | private: 43 | std::unique_ptr jit; 44 | std::unique_ptr context; 45 | std::string target_triple; 46 | llvm::TargetMachine *TM; 47 | public: 48 | LLVMEvaluator(const std::string &t = ""); 49 | ~LLVMEvaluator(); 50 | std::unique_ptr parse_module(const std::string &source); 51 | void add_module(const std::string &source); 52 | void add_module(std::unique_ptr mod); 53 | void add_module(std::unique_ptr m); 54 | intptr_t get_symbol_address(const std::string &name); 55 | int32_t int32fn(const std::string &name); 56 | int64_t int64fn(const std::string &name); 57 | bool boolfn(const std::string &name); 58 | float floatfn(const std::string &name); 59 | double doublefn(const std::string &name); 60 | std::complex complex4fn(const std::string &name); 61 | std::complex complex8fn(const std::string &name); 62 | void voidfn(const std::string &name); 63 | std::string get_asm(llvm::Module &m); 64 | void save_asm_file(llvm::Module &m, const std::string &filename); 65 | void save_object_file(llvm::Module &m, const std::string &filename); 66 | void create_empty_object_file(const std::string &filename); 67 | void opt(llvm::Module &m); 68 | static std::string module_to_string(llvm::Module &m); 69 | static void print_version_message(); 70 | llvm::LLVMContext &get_context(); 71 | static void print_targets(); 72 | static std::string get_default_target_triple(); 73 | }; 74 | 75 | 76 | } // namespace LCompilers 77 | 78 | #endif // LFORTRAN_EVALUATOR_H 79 | -------------------------------------------------------------------------------- /src/libasr/codegen/wasm_to_wat.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_WASM_TO_WAT_H 2 | #define LFORTRAN_WASM_TO_WAT_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | Result wasm_to_wat(Vec &wasm_bytes, Allocator &al, 9 | diag::Diagnostics &diagnostics); 10 | 11 | } // namespace LCompilers 12 | 13 | #endif // LFORTRAN_WASM_TO_WAT_H 14 | -------------------------------------------------------------------------------- /src/libasr/codegen/wasm_to_x64.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_WASM_TO_X64_H 2 | #define LFORTRAN_WASM_TO_X64_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | Result wasm_to_x64(Vec &wasm_bytes, Allocator &al, 9 | const std::string &filename, bool time_report, 10 | diag::Diagnostics &diagnostics); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_WASM_TO_X64_H 15 | -------------------------------------------------------------------------------- /src/libasr/codegen/wasm_to_x86.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_WASM_TO_X86_H 2 | #define LFORTRAN_WASM_TO_X86_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | Result wasm_to_x86(Vec &wasm_bytes, Allocator &al, 9 | const std::string &filename, bool time_report, 10 | diag::Diagnostics &diagnostics); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_WASM_TO_X86_H 15 | -------------------------------------------------------------------------------- /src/libasr/colors.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_COLORS_H 2 | #define LFORTRAN_COLORS_H 3 | 4 | namespace LCompilers { 5 | 6 | enum class style { 7 | reset = 0, 8 | bold = 1, 9 | dim = 2, 10 | italic = 3, 11 | underline = 4, 12 | blink = 5, 13 | rblink = 6, 14 | reversed = 7, 15 | conceal = 8, 16 | crossed = 9 17 | }; 18 | 19 | enum class fg { 20 | black = 30, 21 | red = 31, 22 | green = 32, 23 | yellow = 33, 24 | blue = 34, 25 | magenta = 35, 26 | cyan = 36, 27 | gray = 37, 28 | reset = 39 29 | }; 30 | 31 | enum class bg { 32 | black = 40, 33 | red = 41, 34 | green = 42, 35 | yellow = 43, 36 | blue = 44, 37 | magenta = 45, 38 | cyan = 46, 39 | gray = 47, 40 | reset = 49 41 | }; 42 | 43 | enum class fgB { 44 | black = 90, 45 | red = 91, 46 | green = 92, 47 | yellow = 93, 48 | blue = 94, 49 | magenta = 95, 50 | cyan = 96, 51 | gray = 97 52 | }; 53 | 54 | enum class bgB { 55 | black = 100, 56 | red = 101, 57 | green = 102, 58 | yellow = 103, 59 | blue = 104, 60 | magenta = 105, 61 | cyan = 106, 62 | gray = 107 63 | }; 64 | 65 | 66 | template 67 | std::string color(T const value) 68 | { 69 | return "\033[" + std::to_string(static_cast(value)) + "m"; 70 | } 71 | 72 | 73 | } // namespace LCompilers 74 | 75 | #endif // LFORTRAN_COLORS_H 76 | -------------------------------------------------------------------------------- /src/libasr/compiler_tester/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcompilers/lc/3e3a02699c3365aca0cc6b0e07cc61c161de76c6/src/libasr/compiler_tester/__init__.py -------------------------------------------------------------------------------- /src/libasr/config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_CONFIG_H 2 | #define LFORTRAN_CONFIG_H 3 | 4 | /* Define if you want to enable ASSERT testing in LFortran */ 5 | #cmakedefine WITH_LFORTRAN_ASSERT 6 | 7 | /* LFortran version */ 8 | #cmakedefine LFORTRAN_VERSION "@LFORTRAN_VERSION@" 9 | #define LFORTRAN_MAJOR @CMAKE_PROJECT_VERSION_MAJOR@ 10 | #define LFORTRAN_MINOR @CMAKE_PROJECT_VERSION_MINOR@ 11 | #define LFORTRAN_PATCHLEVEL @CMAKE_PROJECT_VERSION_PATCH@ 12 | 13 | /* Define if LLVM is enabled */ 14 | #cmakedefine HAVE_LFORTRAN_LLVM 15 | 16 | /* Define if RAPIDJSON is found */ 17 | #cmakedefine HAVE_LFORTRAN_RAPIDJSON 18 | 19 | /* Define if stacktrace is enabled */ 20 | #cmakedefine HAVE_LFORTRAN_STACKTRACE 21 | #cmakedefine HAVE_RUNTIME_STACKTRACE 22 | #cmakedefine HAVE_LFORTRAN_BFD 23 | #cmakedefine HAVE_LFORTRAN_DWARFDUMP 24 | #cmakedefine HAVE_LFORTRAN_LINK 25 | #cmakedefine HAVE_LFORTRAN_MACHO 26 | #cmakedefine HAVE_LFORTRAN_UNWIND 27 | 28 | /* Define if cxxabi.h is present */ 29 | #cmakedefine HAVE_LFORTRAN_DEMANGLE 30 | 31 | /* Define if XEUS is enabled */ 32 | #cmakedefine HAVE_LFORTRAN_XEUS 33 | 34 | /* Define if we should use binary modfiles */ 35 | #cmakedefine WITH_LFORTRAN_BINARY_MODFILES 36 | 37 | #endif // LFORTRAN_CONFIG_H 38 | -------------------------------------------------------------------------------- /src/libasr/dat_convert.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from struct import unpack 4 | from sys import argv 5 | from re import sub 6 | 7 | lines = "" 8 | with open(argv[1], "rb") as f: 9 | lines = f.read() 10 | 11 | list = [] 12 | for i in range(0, len(lines), 24): 13 | list.append(sub('[(),]', '', str(unpack("3Q", lines[i:i+24])))) 14 | 15 | with open(argv[1] + ".txt", "w") as f: 16 | j = 0 17 | for i in list: 18 | f.write(i+'\n') 19 | -------------------------------------------------------------------------------- /src/libasr/gen_pass.py: -------------------------------------------------------------------------------- 1 | passes = [ 2 | "replace_arr_slice", 3 | "replace_function_call_in_declaration", 4 | "replace_array_op", 5 | "replace_class_constructor", 6 | "dead_code_removal", 7 | "replace_div_to_mul", 8 | "replace_do_loops", 9 | "replace_flip_sign", 10 | "replace_fma", 11 | "replace_for_all", 12 | "while_else", 13 | "wrap_global_stmts", 14 | "replace_implied_do_loops", 15 | "replace_init_expr", 16 | "inline_function_calls", 17 | "replace_symbolic", 18 | "replace_intrinsic_function", 19 | "loop_unroll", 20 | "loop_vectorise", 21 | "nested_vars", 22 | "replace_param_to_const", 23 | "array_by_data", 24 | "compare", 25 | "list_expr", 26 | "replace_print_arr", 27 | "replace_print_list_tuple", 28 | "replace_print_struct_type", 29 | "replace_select_case", 30 | "replace_sign_from_value", 31 | "create_subroutine_from_function", 32 | "transform_optional_argument_functions", 33 | "unused_functions", 34 | "update_array_dim_intrinsic_calls", 35 | "replace_where", 36 | "unique_symbols", 37 | "insert_deallocate", 38 | "promote_allocatable_to_nonallocatable" 39 | ] 40 | 41 | 42 | 43 | for name in passes: 44 | print(f"Processing: {name}") 45 | name_up = name.upper() 46 | header = rf"""#ifndef LIBASR_PASS_{name_up}_H 47 | #define LIBASR_PASS_{name_up}_H 48 | 49 | #include 50 | #include 51 | 52 | namespace LCompilers {{ 53 | 54 | void pass_{name}(Allocator &al, ASR::TranslationUnit_t &unit, 55 | const PassOptions &pass_options); 56 | 57 | }} // namespace LCompilers 58 | 59 | #endif // LIBASR_PASS_{name_up}_H 60 | """ 61 | header_filename = f"pass/{name}.h" 62 | f = open(header_filename, "w") 63 | f.write(header) 64 | -------------------------------------------------------------------------------- /src/libasr/lsp_interface.h: -------------------------------------------------------------------------------- 1 | #ifndef MESSAGE_HANDLER_HPP 2 | #define MESSAGE_HANDLER_HPP 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | struct error_highlight { 9 | std::string message; 10 | uint32_t first_line; 11 | uint32_t first_column; 12 | uint32_t last_line; 13 | uint32_t last_column; 14 | std::string filename; 15 | uint32_t severity; 16 | }; 17 | struct document_symbols { 18 | std::string symbol_name; 19 | uint32_t first_line; 20 | uint32_t first_column; 21 | uint32_t last_line; 22 | uint32_t last_column; 23 | std::string filename; 24 | }; 25 | 26 | } // namespace LCompilers 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/libasr/modfile.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_MODFILE_H 2 | #define LFORTRAN_MODFILE_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | // Save a module to a modfile 9 | std::string save_modfile(const ASR::TranslationUnit_t &m); 10 | 11 | std::string save_pycfile(const ASR::TranslationUnit_t &m); 12 | 13 | // Load a module from a modfile 14 | ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s, 15 | bool load_symtab_id, SymbolTable &symtab); 16 | 17 | ASR::TranslationUnit_t* load_pycfile(Allocator &al, const std::string &s, 18 | bool load_symtab_id); 19 | 20 | } // namespace LCompilers 21 | 22 | #endif // LFORTRAN_MODFILE_H 23 | -------------------------------------------------------------------------------- /src/libasr/pass/arr_dims_propagate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace LFortran { 10 | 11 | /* 12 | * This ASR pass replaces ttype for all arrays passed. 13 | * 14 | * Converts: 15 | * integer :: a(:, :) 16 | * 17 | * to: 18 | * integer :: a(2, 3) 19 | */ 20 | 21 | class ArrDimsPropagate : public ASR::StatementsFirstBaseWalkVisitor 22 | { 23 | private: 24 | // Allocator &m_al; 25 | public: 26 | ArrDimsPropagate(Allocator &/*al*/) /*: m_al(al)*/ { } 27 | 28 | void visit_FunctionCall(const ASR::FunctionCall_t &x) { 29 | ASR::Function_t *fn = ASR::down_cast(ASRUtils::symbol_get_past_external(x.m_name)); 30 | 31 | for (size_t i = 0; i < x.n_args; i++) { 32 | if (ASR::is_a(*x.m_args[i].m_value) && ASRUtils::is_array(ASRUtils::expr_type(x.m_args[i].m_value))) { 33 | ASR::Variable_t* v = ASRUtils::EXPR2VAR(x.m_args[i].m_value); 34 | ASR::Variable_t *fn_param = ASRUtils::EXPR2VAR(fn->m_args[i]); 35 | ASR::dimension_t* m_dims; 36 | int n_dims = ASRUtils::extract_dimensions_from_ttype(fn_param->m_type, m_dims); 37 | if (n_dims > 0 && !m_dims[0].m_length && ASRUtils::check_equal_type(v->m_type, fn_param->m_type)) { 38 | fn_param->m_type = v->m_type; 39 | } 40 | } 41 | } 42 | } 43 | 44 | void visit_SubroutineCall(const ASR::SubroutineCall_t &x) { 45 | ASR::Subroutine_t *sb = ASR::down_cast(ASRUtils::symbol_get_past_external(x.m_name)); 46 | for (size_t i = 0; i < x.n_args; i++) { 47 | if (ASR::is_a(*x.m_args[i].m_value) && ASRUtils::is_array(ASRUtils::expr_type(x.m_args[i].m_value))) { 48 | ASR::Variable_t* v = ASRUtils::EXPR2VAR(x.m_args[i].m_value); 49 | ASR::Variable_t *sb_param = ASRUtils::EXPR2VAR(sb->m_args[i]); 50 | ASR::dimension_t* m_dims; 51 | int n_dims = ASRUtils::extract_dimensions_from_ttype(sb_param->m_type, m_dims); 52 | if (n_dims > 0 && !m_dims[0].m_length && ASRUtils::check_equal_type(v->m_type, sb_param->m_type)) { 53 | sb_param->m_type = v->m_type; 54 | } 55 | } 56 | } 57 | } 58 | }; 59 | 60 | void pass_propagate_arr_dims(Allocator &al, ASR::TranslationUnit_t &unit) { 61 | ArrDimsPropagate v(al); 62 | v.visit_TranslationUnit(unit); 63 | LFORTRAN_ASSERT(asr_verify(unit)); 64 | } 65 | 66 | } // namespace LFortran 67 | -------------------------------------------------------------------------------- /src/libasr/pass/arr_dims_propagate.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_ARR_DIMS_PROPAGATE 2 | #define LFORTRAN_PASS_ARR_DIMS_PROPAGATE 3 | 4 | #include 5 | 6 | namespace LFortran { 7 | 8 | void pass_propagate_arr_dims(Allocator &al, ASR::TranslationUnit_t &unit); 9 | 10 | } // namespace LFortran 11 | 12 | #endif // LFORTRAN_PASS_ARR_DIMS_PROPAGATE 13 | -------------------------------------------------------------------------------- /src/libasr/pass/arr_slice.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_ARR_SLICE_H 2 | #define LFORTRAN_PASS_ARR_SLICE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_arr_slice(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_ARR_SLICE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/array_by_data.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_ARRAY_BY_DATA_H 2 | #define LIBASR_PASS_ARRAY_BY_DATA_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_array_by_data(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_ARRAY_BY_DATA_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/array_op.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_ARRAY_OP_H 2 | #define LFORTRAN_PASS_ARRAY_OP_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_array_op(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_ARRAY_OP_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/class_constructor.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_CLASS_CONSTRUCTOR_H 2 | #define LFORTRAN_PASS_CLASS_CONSTRUCTOR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_class_constructor(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_CLASS_CONSTRUCTOR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/compare.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_COMPARE_H 2 | #define LIBASR_PASS_COMPARE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_compare(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_COMPARE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/create_subroutine_from_function.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_CREATE_SUBROUTINE_FROM_FUNCTION_H 2 | #define LIBASR_PASS_CREATE_SUBROUTINE_FROM_FUNCTION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_create_subroutine_from_function(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_CREATE_SUBROUTINE_FROM_FUNCTION_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/dead_code_removal.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_DEAD_CODE_REMOVAL_H 2 | #define LIBASR_PASS_DEAD_CODE_REMOVAL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_dead_code_removal(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_DEAD_CODE_REMOVAL_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/div_to_mul.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | 13 | namespace LCompilers { 14 | 15 | using ASR::down_cast; 16 | using ASR::is_a; 17 | 18 | /* 19 | 20 | This ASR pass replaces division operation with multiplication 21 | if the divisor can be evaluated to a constant at compile time. 22 | 23 | Converts: 24 | 25 | real :: x 26 | real, parameter :: divisor = 2.0 27 | print *, x/divisor 28 | 29 | to: 30 | 31 | real :: x 32 | real, parameter :: divisor = 2.0 33 | print *, x * 0.5 34 | 35 | */ 36 | class DivToMulVisitor : public PassUtils::PassVisitor 37 | { 38 | private: 39 | 40 | std::string rl_path; 41 | 42 | public: 43 | DivToMulVisitor(Allocator &al_, const std::string& rl_path_) : PassVisitor(al_, nullptr), 44 | rl_path(rl_path_) 45 | { 46 | pass_result.reserve(al, 1); 47 | } 48 | 49 | void visit_RealBinOp(const ASR::RealBinOp_t& x) { 50 | visit_expr(*x.m_left); 51 | visit_expr(*x.m_right); 52 | if( x.m_op == ASR::binopType::Div ) { 53 | ASR::expr_t* right_value = ASRUtils::expr_value(x.m_right); 54 | if( right_value ) { 55 | double value; 56 | if( ASRUtils::extract_value(right_value, value) ) { 57 | bool is_feasible = false; 58 | ASR::expr_t* right_inverse = nullptr; 59 | switch( x.m_type->type ) { 60 | case ASR::ttypeType::Real: { 61 | is_feasible = true; 62 | right_inverse = ASRUtils::EXPR(ASR::make_RealConstant_t(al, x.m_right->base.loc, 1.0/value, x.m_type)); 63 | break; 64 | } 65 | default: 66 | break; 67 | } 68 | if( is_feasible ) { 69 | ASR::RealBinOp_t& xx = const_cast(x); 70 | xx.m_op = ASR::binopType::Mul; 71 | xx.m_right = right_inverse; 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | }; 79 | 80 | void pass_replace_div_to_mul(Allocator &al, ASR::TranslationUnit_t &unit, 81 | const LCompilers::PassOptions& pass_options) { 82 | std::string rl_path = pass_options.runtime_library_dir; 83 | DivToMulVisitor v(al, rl_path); 84 | v.visit_TranslationUnit(unit); 85 | } 86 | 87 | 88 | } // namespace LCompilers 89 | -------------------------------------------------------------------------------- /src/libasr/pass/div_to_mul.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_DIV_TO_MUL_H 2 | #define LIBASR_PASS_DIV_TO_MUL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_div_to_mul(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_DIV_TO_MUL_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/do_loops.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace LCompilers { 11 | 12 | using ASR::down_cast; 13 | using ASR::is_a; 14 | 15 | /* 16 | 17 | This ASR pass replaces do loops with while loops. The function 18 | `pass_replace_do_loops` transforms the ASR tree in-place. 19 | 20 | Converts: 21 | 22 | do i = a, b, c 23 | ... 24 | end do 25 | 26 | to: 27 | 28 | i = a-c 29 | do while (i+c <= b) 30 | i = i+c 31 | ... 32 | end do 33 | 34 | The comparison is >= for c<0. 35 | */ 36 | class DoLoopVisitor : public ASR::StatementWalkVisitor 37 | { 38 | public: 39 | bool use_loop_variable_after_loop = false; 40 | DoLoopVisitor(Allocator &al) : StatementWalkVisitor(al) { 41 | } 42 | 43 | void visit_DoLoop(const ASR::DoLoop_t &x) { 44 | pass_result = PassUtils::replace_doloop(al, x, -1, use_loop_variable_after_loop); 45 | } 46 | 47 | void visit_DoConcurrentLoop(const ASR::DoConcurrentLoop_t &x) { 48 | ASR::asr_t* do_loop = ASR::make_DoLoop_t(al, x.base.base.loc, s2c(al, ""), x.m_head, x.m_body, x.n_body, nullptr, 0); 49 | const ASR::DoLoop_t &do_loop_ref = (const ASR::DoLoop_t&)(*do_loop); 50 | pass_result = PassUtils::replace_doloop(al, do_loop_ref, -1, use_loop_variable_after_loop); 51 | } 52 | }; 53 | 54 | void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, 55 | const LCompilers::PassOptions& pass_options) { 56 | DoLoopVisitor v(al); 57 | // Each call transforms only one layer of nested loops, so we call it twice 58 | // to transform doubly nested loops: 59 | v.asr_changed = true; 60 | v.use_loop_variable_after_loop = pass_options.use_loop_variable_after_loop; 61 | while( v.asr_changed ) { 62 | v.asr_changed = false; 63 | v.visit_TranslationUnit(unit); 64 | } 65 | } 66 | 67 | 68 | } // namespace LCompilers 69 | -------------------------------------------------------------------------------- /src/libasr/pass/do_loops.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_DO_LOOPS_H 2 | #define LFORTRAN_PASS_DO_LOOPS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_DO_LOOPS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/flip_sign.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_FLIP_SIGN_H 2 | #define LIBASR_PASS_FLIP_SIGN_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_flip_sign(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_FLIP_SIGN_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/fma.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_FMA_H 2 | #define LIBASR_PASS_FMA_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_fma(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_FMA_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/for_all.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace LCompilers { 10 | 11 | /* 12 | * This ASR pass replaces forall statement with Do Concurrent. 13 | * 14 | * Converts: 15 | * forall(i=start:end:inc) array(i) = i 16 | * 17 | * to: 18 | * do concurrent (i=start:end:inc) 19 | * array(i) = i 20 | * end do 21 | */ 22 | 23 | class ForAllVisitor : public ASR::StatementWalkVisitor 24 | { 25 | public: 26 | ForAllVisitor(Allocator &al) : StatementWalkVisitor(al) { 27 | } 28 | 29 | void visit_ForAllSingle(const ASR::ForAllSingle_t &x) { 30 | Location loc = x.base.base.loc; 31 | ASR::stmt_t *assign_stmt = x.m_assign_stmt; 32 | Vec body; 33 | body.reserve(al, 1); 34 | body.push_back(al, assign_stmt); 35 | 36 | ASR::stmt_t *stmt = ASRUtils::STMT( 37 | ASR::make_DoConcurrentLoop_t(al, loc, x.m_head, body.p, body.size()) 38 | ); 39 | Vec result; 40 | result.reserve(al, 1); 41 | result.push_back(al, stmt); 42 | pass_result = result; 43 | } 44 | }; 45 | 46 | void pass_replace_for_all(Allocator &al, ASR::TranslationUnit_t &unit, 47 | const LCompilers::PassOptions& /*pass_options*/) { 48 | ForAllVisitor v(al); 49 | v.visit_TranslationUnit(unit); 50 | } 51 | 52 | } // namespace LCompilers 53 | -------------------------------------------------------------------------------- /src/libasr/pass/for_all.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_FOR_ALL 2 | #define LFORTRAN_PASS_FOR_ALL 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_forall(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_FOR_ALL 15 | -------------------------------------------------------------------------------- /src/libasr/pass/global_stmts.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_GLOBAL_STMTS_H 2 | #define LFORTRAN_PASS_GLOBAL_STMTS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_wrap_global_stmts_into_function(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_GLOBAL_STMTS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/global_stmts_program.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | namespace LCompilers { 11 | 12 | using ASR::down_cast; 13 | 14 | using ASRUtils::EXPR; 15 | 16 | /* 17 | * This ASR pass transforms (in-place) the ASR tree and wraps all global 18 | * statements and expressions into a program. 19 | * 20 | */ 21 | void pass_wrap_global_stmts_into_program(Allocator &al, 22 | ASR::TranslationUnit_t &unit, const LCompilers::PassOptions& pass_options) { 23 | std::string program_fn_name = pass_options.run_fun; 24 | SymbolTable *current_scope = al.make_new(unit.m_global_scope); 25 | std::string prog_name = "main_program"; 26 | Vec prog_body; 27 | prog_body.reserve(al, 1); 28 | SetChar prog_dep; 29 | prog_dep.reserve(al, 1); 30 | bool call_main_program = unit.n_items > 0; 31 | pass_wrap_global_stmts_into_function(al, unit, pass_options); 32 | pass_wrap_global_syms_into_module(al, unit, pass_options); 33 | if( call_main_program && !pass_options.disable_main ) { 34 | // Call `_lpython_main_program` function 35 | ASR::Module_t *mod = ASR::down_cast( 36 | unit.m_global_scope->get_symbol("_global_symbols")); 37 | ASR::symbol_t *fn_s = mod->m_symtab->get_symbol(program_fn_name); 38 | if (!(ASR::is_a(*fn_s) 39 | && ASR::down_cast(fn_s)->m_return_var == nullptr)) { 40 | throw LCompilersException("Return type not supported yet"); 41 | } 42 | 43 | ASR::Function_t *fn = ASR::down_cast(fn_s); 44 | fn_s = ASR::down_cast(ASR::make_ExternalSymbol_t( 45 | al, fn->base.base.loc, current_scope, s2c(al, program_fn_name), 46 | fn_s, mod->m_name, nullptr, 0, s2c(al, program_fn_name), 47 | ASR::accessType::Public)); 48 | current_scope->add_symbol(program_fn_name, fn_s); 49 | ASR::asr_t *stmt = ASR::make_SubroutineCall_t( 50 | al, unit.base.base.loc, 51 | fn_s, nullptr, 52 | nullptr, 0, 53 | nullptr); 54 | prog_body.push_back(al, ASR::down_cast(stmt)); 55 | prog_dep.push_back(al, s2c(al, "_global_symbols")); 56 | } 57 | 58 | if( !pass_options.disable_main ) { 59 | ASR::asr_t *prog = ASR::make_Program_t( 60 | al, unit.base.base.loc, 61 | /* a_symtab */ current_scope, 62 | /* a_name */ s2c(al, prog_name), 63 | prog_dep.p, 64 | prog_dep.n, 65 | /* a_body */ prog_body.p, 66 | /* n_body */ prog_body.n); 67 | unit.m_global_scope->add_symbol(prog_name, ASR::down_cast(prog)); 68 | } 69 | } 70 | 71 | } // namespace LCompilers 72 | -------------------------------------------------------------------------------- /src/libasr/pass/global_stmts_program.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_GLOBAL_STMTS_PROGRAM_H 2 | #define LIBASR_PASS_GLOBAL_STMTS_PROGRAM_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_wrap_global_stmts_into_program(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_GLOBAL_STMTS_PROGRAM_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/global_symbols.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | namespace LCompilers { 11 | 12 | /* 13 | * This ASR pass transforms (in-place) the ASR tree 14 | * and wraps all global symbols into a module 15 | */ 16 | 17 | void pass_wrap_global_syms_into_module(Allocator &al, 18 | ASR::TranslationUnit_t &unit, 19 | const LCompilers::PassOptions &/*pass_options*/) { 20 | if( unit.m_global_scope->get_scope().size() == 0 ) { 21 | return ; 22 | } 23 | Location loc = unit.base.base.loc; 24 | char *module_name = s2c(al, "_global_symbols"); 25 | SymbolTable *module_scope = al.make_new(unit.m_global_scope); 26 | Vec moved_symbols; 27 | SetChar mod_dependencies; 28 | 29 | // Move all the symbols from global into the module scope 30 | unit.m_global_scope->move_symbols_from_global_scope(al, module_scope, 31 | moved_symbols, mod_dependencies); 32 | 33 | // Erase the symbols that are moved into the module 34 | for (auto &sym: moved_symbols) { 35 | unit.m_global_scope->erase_symbol(sym); 36 | } 37 | 38 | ASR::symbol_t *module = (ASR::symbol_t *) ASR::make_Module_t(al, loc, 39 | module_scope, module_name, mod_dependencies.p, mod_dependencies.n, 40 | false, false); 41 | unit.m_global_scope->add_symbol(module_name, module); 42 | } 43 | 44 | } // namespace LCompilers 45 | -------------------------------------------------------------------------------- /src/libasr/pass/global_symbols.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_GLOBAL_SYMBOLS_H 2 | #define LFORTRAN_PASS_GLOBAL_SYMBOLS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_wrap_global_syms_into_module(Allocator &al, 10 | ASR::TranslationUnit_t &unit, 11 | const LCompilers::PassOptions& pass_options); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_PASS_GLOBAL_SYMBOLS_H 16 | -------------------------------------------------------------------------------- /src/libasr/pass/implied_do_loops.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_IMPLIED_DO_LOOPS_H 2 | #define LFORTRAN_PASS_IMPLIED_DO_LOOPS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_implied_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_IMPLIED_DO_LOOPS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/init_expr.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_INIT_EXPR_H 2 | #define LFORTRAN_PASS_INIT_EXPR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_init_expr(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_INIT_EXPR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/inline_function_calls.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_INLINE_FUNCTION_CALLS_H 2 | #define LIBASR_PASS_INLINE_FUNCTION_CALLS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_inline_function_calls(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_INLINE_FUNCTION_CALLS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/insert_deallocate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | 12 | namespace LCompilers { 13 | 14 | class InsertDeallocate: public ASR::CallReplacerOnExpressionsVisitor 15 | { 16 | private: 17 | 18 | Allocator& al; 19 | 20 | public: 21 | 22 | InsertDeallocate(Allocator& al_) : al(al_) {} 23 | 24 | template 25 | void visit_Symbol(const T& x) { 26 | Vec to_be_deallocated; 27 | to_be_deallocated.reserve(al, 1); 28 | for( auto& itr: x.m_symtab->get_scope() ) { 29 | if( ASR::is_a(*itr.second) && 30 | ASR::is_a(*ASRUtils::symbol_type(itr.second)) && 31 | ASRUtils::is_array(ASRUtils::symbol_type(itr.second)) && 32 | ASRUtils::symbol_intent(itr.second) == ASRUtils::intent_local ) { 33 | to_be_deallocated.push_back(al, ASRUtils::EXPR( 34 | ASR::make_Var_t(al, x.base.base.loc, itr.second))); 35 | } 36 | } 37 | if( to_be_deallocated.size() > 0 ) { 38 | T& xx = const_cast(x); 39 | Vec body; 40 | body.from_pointer_n_copy(al, xx.m_body, xx.n_body); 41 | body.push_back(al, ASRUtils::STMT(ASR::make_ImplicitDeallocate_t( 42 | al, x.base.base.loc, to_be_deallocated.p, to_be_deallocated.size()))); 43 | xx.m_body = body.p; 44 | xx.n_body = body.size(); 45 | } 46 | } 47 | 48 | void visit_Function(const ASR::Function_t& x) { 49 | visit_Symbol(x); 50 | ASR::CallReplacerOnExpressionsVisitor::visit_Function(x); 51 | } 52 | 53 | void visit_Program(const ASR::Program_t& x) { 54 | visit_Symbol(x); 55 | ASR::CallReplacerOnExpressionsVisitor::visit_Program(x); 56 | } 57 | 58 | }; 59 | 60 | void pass_insert_deallocate(Allocator &al, ASR::TranslationUnit_t &unit, 61 | const PassOptions &/*pass_options*/) { 62 | InsertDeallocate v(al); 63 | v.visit_TranslationUnit(unit); 64 | } 65 | 66 | 67 | } // namespace LCompilers 68 | -------------------------------------------------------------------------------- /src/libasr/pass/insert_deallocate.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_INSERT_DEALLOCATE_H 2 | #define LIBASR_PASS_INSERT_DEALLOCATE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_insert_deallocate(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_INSERT_DEALLOCATE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/instantiate_template.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_INSTANTIATE_TEMPLATE_H 2 | #define LIBASR_PASS_INSTANTIATE_TEMPLATE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | namespace LPython { 10 | 11 | /** 12 | * @brief Instantiate a generic function into a function that does not 13 | * contain any type parameters and restrictions. No type checking 14 | * is executed here 15 | */ 16 | ASR::symbol_t* instantiate_symbol(Allocator &al, 17 | std::map &context_map, 18 | std::map type_subs, 19 | std::map symbol_subs, 20 | SymbolTable *current_scope, SymbolTable *template_scope, 21 | std::string new_sym_name, ASR::symbol_t *sym); 22 | 23 | ASR::symbol_t* instantiate_function_body(Allocator &al, 24 | std::map &context_map, 25 | std::map type_subs, 26 | std::map symbol_subs, 27 | SymbolTable *current_scope, SymbolTable *template_scope, 28 | ASR::Function_t *new_f, ASR::Function_t *f); 29 | 30 | ASR::symbol_t* rename_symbol(Allocator &al, 31 | std::map &type_subs, 32 | SymbolTable *current_scope, 33 | std::string new_sym_name, ASR::symbol_t *sym); 34 | 35 | bool check_restriction(std::map type_subs, 36 | std::map &symbol_subs, 37 | ASR::Function_t *f, ASR::symbol_t *sym_arg); 38 | 39 | void report_check_restriction(std::map type_subs, 40 | std::map &symbol_subs, 41 | ASR::Function_t *f, ASR::symbol_t *sym_arg, const Location &loc, 42 | diag::Diagnostics &diagnostics); 43 | 44 | } 45 | 46 | namespace LFortran { 47 | 48 | /** 49 | * @brief Instantiate a generic function into a function that does not 50 | * contain any type parameters and restrictions. No type checking 51 | * is executed here 52 | */ 53 | ASR::symbol_t* instantiate_symbol(Allocator& al, 54 | SymbolTable* target_scope, 55 | std::map type_subs, 56 | std::map& symbol_subs, 57 | std::string new_sym_name, ASR::symbol_t* sym); 58 | 59 | 60 | void instantiate_body(Allocator& al, 61 | std::map type_subs, 62 | std::map& symbol_subs, 63 | ASR::symbol_t* new_sym, ASR::symbol_t* sym); 64 | 65 | 66 | ASR::symbol_t* rename_symbol(Allocator &al, 67 | std::map &type_subs, 68 | SymbolTable *current_scope, 69 | std::string new_sym_name, ASR::symbol_t *sym); 70 | 71 | 72 | bool check_restriction(std::map type_subs, 73 | std::map &symbol_subs, 74 | ASR::Function_t *f, ASR::symbol_t *sym_arg, const Location &loc, 75 | diag::Diagnostics &diagnostics, 76 | const std::function semantic_abort, bool report=true); 77 | 78 | } 79 | 80 | } // namespace LCompilers 81 | 82 | #endif // LIBASR_PASS_INSTANTIATE_TEMPLATE_H 83 | -------------------------------------------------------------------------------- /src/libasr/pass/intrinsic_function.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_INTRINSIC_FUNCTION_H 2 | #define LIBASR_PASS_INTRINSIC_FUNCTION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_intrinsic_function(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_INTRINSIC_FUNCTION_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/intrinsic_subroutine_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_INTRINSIC_SUBROUTINE_REGISTRY_H 2 | #define LFORTRAN_PASS_INTRINSIC_SUBROUTINE_REGISTRY_H 3 | 4 | // #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace LCompilers { 12 | 13 | namespace ASRUtils { 14 | 15 | #define INTRINSIC_SUBROUTINE_NAME_CASE(X) \ 16 | case (static_cast(ASRUtils::IntrinsicImpureSubroutines::X)) : { \ 17 | return #X; \ 18 | } 19 | 20 | inline std::string get_intrinsic_subroutine_name(int x) { 21 | switch (x) { 22 | INTRINSIC_SUBROUTINE_NAME_CASE(RandomNumber) 23 | default : { 24 | throw LCompilersException("pickle: intrinsic_id not implemented"); 25 | } 26 | } 27 | } 28 | 29 | /************************* Intrinsic Impure Subroutine **************************/ 30 | 31 | namespace IntrinsicImpureSubroutineRegistry { 32 | 33 | static const std::map>& intrinsic_subroutine_by_id_db = { 36 | {static_cast(IntrinsicImpureSubroutines::RandomNumber), 37 | {&RandomNumber::instantiate_RandomNumber, &RandomNumber::verify_args}}, 38 | }; 39 | 40 | static const std::map& intrinsic_subroutine_id_to_name = { 41 | {static_cast(IntrinsicImpureSubroutines::RandomNumber), 42 | "random_number"}, 43 | }; 44 | 45 | 46 | static const std::map& intrinsic_subroutine_by_name_db = { 48 | {"random_number", &RandomNumber::create_RandomNumber}, 49 | }; 50 | 51 | static inline bool is_intrinsic_subroutine(const std::string& name) { 52 | return intrinsic_subroutine_by_name_db.find(name) != intrinsic_subroutine_by_name_db.end(); 53 | } 54 | 55 | static inline bool is_intrinsic_subroutine(int64_t id) { 56 | return intrinsic_subroutine_by_id_db.find(id) != intrinsic_subroutine_by_id_db.end(); 57 | } 58 | 59 | static inline create_intrinsic_subroutine get_create_subroutine(const std::string& name) { 60 | return intrinsic_subroutine_by_name_db.at(name); 61 | } 62 | 63 | static inline verify_subroutine get_verify_subroutine(int64_t id) { 64 | return std::get<1>(intrinsic_subroutine_by_id_db.at(id)); 65 | } 66 | 67 | static inline impl_subroutine get_instantiate_subroutine(int64_t id) { 68 | if( intrinsic_subroutine_by_id_db.find(id) == intrinsic_subroutine_by_id_db.end() ) { 69 | return nullptr; 70 | } 71 | return std::get<0>(intrinsic_subroutine_by_id_db.at(id)); 72 | } 73 | 74 | static inline std::string get_intrinsic_subroutine_name(int64_t id) { 75 | if( intrinsic_subroutine_id_to_name.find(id) == intrinsic_subroutine_id_to_name.end() ) { 76 | throw LCompilersException("IntrinsicSubroutine with ID " + std::to_string(id) + 77 | " has no name registered for it"); 78 | } 79 | return intrinsic_subroutine_id_to_name.at(id); 80 | } 81 | 82 | } // namespace IntrinsicImpureSubroutineRegistry 83 | 84 | } // namespace ASRUtils 85 | 86 | } // namespace LCompilers 87 | 88 | #endif // LFORTRAN_PASS_INTRINSIC_SUBROUTINE_REGISTRY_H 89 | -------------------------------------------------------------------------------- /src/libasr/pass/list_expr.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_LIST_EXPR_H 2 | #define LIBASR_PASS_LIST_EXPR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_list_expr(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_LIST_EXPR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/loop_unroll.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_LOOP_UNROLL_H 2 | #define LIBASR_PASS_LOOP_UNROLL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_loop_unroll(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_LOOP_UNROLL_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/loop_vectorise.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_LOOP_VECTORISE_H 2 | #define LIBASR_PASS_LOOP_VECTORISE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_loop_vectorise(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_LOOP_VECTORISE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/nested_vars.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_NESTED_VARS_H 2 | #define LIBASR_PASS_NESTED_VARS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_nested_vars(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_NESTED_VARS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/param_to_const.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_PARAM_TO_CONST_H 2 | #define LFORTRAN_PASS_PARAM_TO_CONST_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_param_to_const(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options 11 | ); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_PASS_PARAM_TO_CONST_H 16 | -------------------------------------------------------------------------------- /src/libasr/pass/pass_array_by_data.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_ARRAY_BY_DATA_H 2 | #define LFORTRAN_PASS_ARRAY_BY_DATA_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_array_by_data(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_ARRAY_BY_DATA_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/pass_compare.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_COMPARE_H 2 | #define LIBASR_PASS_COMPARE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_compare(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& /*pass_options*/); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_COMPARE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/pass_list_concat.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_LIST_CONCAT_H 2 | #define LIBASR_PASS_LIST_CONCAT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LFortran { 8 | 9 | void pass_list_concat(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& /*pass_options*/); 11 | 12 | } // namespace LFortran 13 | 14 | #endif // LIBASR_PASS_LIST_CONCAT_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/pass_list_expr.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_LIST_EXPR_H 2 | #define LIBASR_PASS_LIST_EXPR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_list_expr(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& /*pass_options*/); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_LIST_EXPR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/print_arr.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_PRINT_ARR_H 2 | #define LFORTRAN_PASS_PRINT_ARR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_print_arr(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_PRINT_ARR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/print_list.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_PRINT_LIST_H 2 | #define LFORTRAN_PASS_PRINT_LIST_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_print_list( 10 | Allocator &al, ASR::TranslationUnit_t &unit, 11 | const LCompilers::PassOptions &pass_options); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_PASS_PRINT_LIST_H 16 | -------------------------------------------------------------------------------- /src/libasr/pass/print_list_tuple.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_PRINT_LIST_TUPLE_H 2 | #define LFORTRAN_PASS_PRINT_LIST_TUPLE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_print_list_tuple( 10 | Allocator &al, ASR::TranslationUnit_t &unit, 11 | const LCompilers::PassOptions &pass_options); 12 | 13 | } // namespace LCompilers 14 | 15 | #endif // LFORTRAN_PASS_PRINT_LIST_TUPLE_H 16 | -------------------------------------------------------------------------------- /src/libasr/pass/promote_allocatable_to_nonallocatable.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_PROMOTE_ALLOCATABLE_TO_NONALLOCATABLE_H 2 | #define LIBASR_PASS_PROMOTE_ALLOCATABLE_TO_NONALLOCATABLE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_promote_allocatable_to_nonallocatable(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_PROMOTE_ALLOCATABLE_TO_NONALLOCATABLE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_arr_slice.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_ARR_SLICE_H 2 | #define LIBASR_PASS_REPLACE_ARR_SLICE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_arr_slice(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_ARR_SLICE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_array_op.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_ARRAY_OP_H 2 | #define LIBASR_PASS_REPLACE_ARRAY_OP_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_array_op(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_ARRAY_OP_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_class_constructor.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_CLASS_CONSTRUCTOR_H 2 | #define LIBASR_PASS_REPLACE_CLASS_CONSTRUCTOR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_class_constructor(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_CLASS_CONSTRUCTOR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_div_to_mul.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_DIV_TO_MUL_H 2 | #define LIBASR_PASS_REPLACE_DIV_TO_MUL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_div_to_mul(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_DIV_TO_MUL_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_do_loops.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_DO_LOOPS_H 2 | #define LIBASR_PASS_REPLACE_DO_LOOPS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_DO_LOOPS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_flip_sign.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_FLIP_SIGN_H 2 | #define LIBASR_PASS_REPLACE_FLIP_SIGN_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_flip_sign(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_FLIP_SIGN_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_fma.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_FMA_H 2 | #define LIBASR_PASS_REPLACE_FMA_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_fma(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_FMA_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_for_all.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_FOR_ALL_H 2 | #define LIBASR_PASS_REPLACE_FOR_ALL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_for_all(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_FOR_ALL_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_function_call_in_declaration.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_FUNCTION_CALL_IN_DECLARATION_H 2 | #define LIBASR_PASS_REPLACE_FUNCTION_CALL_IN_DECLARATION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_function_call_in_declaration(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_FUNCTION_CALL_IN_DECLARATION_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_implied_do_loops.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_IMPLIED_DO_LOOPS_H 2 | #define LIBASR_PASS_REPLACE_IMPLIED_DO_LOOPS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_implied_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_IMPLIED_DO_LOOPS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_init_expr.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_INIT_EXPR_H 2 | #define LIBASR_PASS_REPLACE_INIT_EXPR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_init_expr(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_INIT_EXPR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_intrinsic_function.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_INTRINSIC_FUNCTION_H 2 | #define LIBASR_PASS_REPLACE_INTRINSIC_FUNCTION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_intrinsic_function(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_INTRINSIC_FUNCTION_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_intrinsic_subroutine.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_INTRINSIC_SUBROUTINE_H 2 | #define LIBASR_PASS_REPLACE_INTRINSIC_SUBROUTINE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_intrinsic_subroutine(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_INTRINSIC_SUBROUTINE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_param_to_const.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_PARAM_TO_CONST_H 2 | #define LIBASR_PASS_REPLACE_PARAM_TO_CONST_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_param_to_const(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_PARAM_TO_CONST_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_print_arr.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_PRINT_ARR_H 2 | #define LIBASR_PASS_REPLACE_PRINT_ARR_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_print_arr(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_PRINT_ARR_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_print_list_tuple.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_PRINT_LIST_TUPLE_H 2 | #define LIBASR_PASS_REPLACE_PRINT_LIST_TUPLE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_print_list_tuple(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_PRINT_LIST_TUPLE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_print_struct_type.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_PRINT_STRUCT_TYPE_H 2 | #define LIBASR_PASS_REPLACE_PRINT_STRUCT_TYPE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_print_struct_type(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_PRINT_STRUCT_TYPE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_select_case.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_SELECT_CASE_H 2 | #define LIBASR_PASS_REPLACE_SELECT_CASE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_select_case(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_SELECT_CASE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_sign_from_value.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_SIGN_FROM_VALUE_H 2 | #define LIBASR_PASS_REPLACE_SIGN_FROM_VALUE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_sign_from_value(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_SIGN_FROM_VALUE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_symbolic.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_SYMBOLIC_H 2 | #define LIBASR_PASS_REPLACE_SYMBOLIC_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_symbolic(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_SYMBOLIC_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/replace_where.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_REPLACE_WHERE_H 2 | #define LIBASR_PASS_REPLACE_WHERE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_where(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_REPLACE_WHERE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/select_case.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_SELECT_CASE_H 2 | #define LFORTRAN_PASS_SELECT_CASE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_select_case(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LFORTRAN_PASS_SELECT_CASE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/sign_from_value.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_SIGN_FROM_VALUE_H 2 | #define LIBASR_PASS_SIGN_FROM_VALUE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_sign_from_value(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_SIGN_FROM_VALUE_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/stmt_walk_visitor.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace LCompilers { 4 | 5 | namespace ASR { 6 | template 7 | class StatementWalkVisitor : public PassUtils::PassVisitor 8 | { 9 | 10 | public: 11 | 12 | StatementWalkVisitor(Allocator &al_) : PassUtils::PassVisitor(al_, nullptr) { 13 | } 14 | 15 | void visit_WhileLoop(const ASR::WhileLoop_t &x) { 16 | // FIXME: this is a hack, we need to pass in a non-const `x`, 17 | // which requires to generate a TransformVisitor. 18 | ASR::WhileLoop_t &xx = const_cast(x); 19 | PassUtils::PassVisitor::transform_stmts(xx.m_body, xx.n_body); 20 | } 21 | 22 | void visit_DoLoop(const ASR::DoLoop_t &x) { 23 | // FIXME: this is a hack, we need to pass in a non-const `x`, 24 | // which requires to generate a TransformVisitor. 25 | ASR::DoLoop_t &xx = const_cast(x); 26 | PassUtils::PassVisitor::transform_stmts(xx.m_body, xx.n_body); 27 | } 28 | }; 29 | } // namespace ASR 30 | 31 | } // namespace LCompilers 32 | -------------------------------------------------------------------------------- /src/libasr/pass/subroutine_from_function.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_SUBROUTINE_FROM_FUNCTION_H 2 | #define LIBASR_PASS_SUBROUTINE_FROM_FUNCTION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_create_subroutine_from_function(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const LCompilers::PassOptions& pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_SUBROUTINE_FROM_FUNCTION_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/transform_optional_argument_functions.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_TRANSFORM_OPTIONAL_ARGUMENT_FUNCTIONS_H 2 | #define LIBASR_PASS_TRANSFORM_OPTIONAL_ARGUMENT_FUNCTIONS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_transform_optional_argument_functions(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_TRANSFORM_OPTIONAL_ARGUMENT_FUNCTIONS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/unique_symbols.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_UNIQUE_SYMBOLS_H 2 | #define LIBASR_PASS_UNIQUE_SYMBOLS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_UNIQUE_SYMBOLS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/unused_functions.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_UNUSED_FUNCTIONS_H 2 | #define LIBASR_PASS_UNUSED_FUNCTIONS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_unused_functions(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_UNUSED_FUNCTIONS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/update_array_dim_intrinsic_calls.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_UPDATE_ARRAY_DIM_INTRINSIC_CALLS_H 2 | #define LIBASR_PASS_UPDATE_ARRAY_DIM_INTRINSIC_CALLS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_update_array_dim_intrinsic_calls(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_UPDATE_ARRAY_DIM_INTRINSIC_CALLS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pass/where.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_PASS_WHERE_H 2 | #define LFORTRAN_PASS_WHERE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_replace_where(Allocator &al, ASR::TranslationUnit_t &unit, const LCompilers::PassOptions& pass_options); 10 | 11 | } // namespace LCompilers 12 | 13 | #endif // LFORTRAN_PASS_WHERE_H 14 | -------------------------------------------------------------------------------- /src/libasr/pass/while_else.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_WHILE_ELSE_H 2 | #define LIBASR_PASS_WHILE_ELSE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_while_else(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | } // namespace LCompilers 12 | 13 | #endif // LIBASR_PASS_WHILE_ELSE_H 14 | 15 | -------------------------------------------------------------------------------- /src/libasr/pass/wrap_global_stmts.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PASS_WRAP_GLOBAL_STMTS_H 2 | #define LIBASR_PASS_WRAP_GLOBAL_STMTS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | void pass_wrap_global_stmts(Allocator &al, ASR::TranslationUnit_t &unit, 10 | const PassOptions &pass_options); 11 | 12 | } // namespace LCompilers 13 | 14 | #endif // LIBASR_PASS_WRAP_GLOBAL_STMTS_H 15 | -------------------------------------------------------------------------------- /src/libasr/pickle.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_PICKLE_H 2 | #define LIBASR_PICKLE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace LCompilers { 8 | 9 | // Pickle an ASR node 10 | std::string pickle(ASR::asr_t &asr, bool colors=false, bool indent=false, 11 | bool show_intrinsic_modules=false); 12 | std::string pickle(ASR::TranslationUnit_t &asr, bool colors=false, 13 | bool indent=false, bool show_intrinsic_modules=false); 14 | 15 | // Print the tree structure 16 | std::string pickle_tree(ASR::asr_t &asr, bool colors, bool show_intrinsic_modules=false); 17 | std::string pickle_tree(ASR::TranslationUnit_t &asr, bool colors, bool show_intrinsic_modules=false); 18 | 19 | // Print Json structure 20 | std::string pickle_json(ASR::asr_t &asr, LocationManager &lm, bool no_loc, bool show_intrinsic_modules); 21 | std::string pickle_json(ASR::TranslationUnit_t &asr, LocationManager &lm, bool no_loc, bool show_intrinsic_modules); 22 | 23 | } // namespace LCompilers 24 | 25 | #endif // LIBASR_PICKLE_H 26 | -------------------------------------------------------------------------------- /src/libasr/semantic_exception.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_SEMANTICS_SEMANTIC_EXCEPTION_H 2 | #define LFORTRAN_SEMANTICS_SEMANTIC_EXCEPTION_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | // This exception is only used internally in the lfortran/semantics/ directory 9 | // and in lfortran/asr_utils.h/cpp. Nowhere else. 10 | 11 | class SemanticError 12 | { 13 | public: 14 | diag::Diagnostic d; 15 | public: 16 | SemanticError(const std::string &msg, const Location &loc) 17 | : d{diag::Diagnostic(msg, diag::Level::Error, diag::Stage::Semantic, { 18 | diag::Label("", {loc}) 19 | })} 20 | { } 21 | 22 | SemanticError(const diag::Diagnostic &d) : d{d} { } 23 | }; 24 | 25 | class SemanticAbort 26 | { 27 | }; 28 | 29 | } // namespace LCompilers 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/libasr/serialization.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBASR_SERIALIZATION_H 2 | #define LIBASR_SERIALIZATION_H 3 | 4 | #include 5 | 6 | namespace LCompilers { 7 | 8 | std::string serialize(const ASR::asr_t &asr); 9 | std::string serialize(const ASR::TranslationUnit_t &unit); 10 | ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s, 11 | bool load_symtab_id, SymbolTable &symtab); 12 | ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s, 13 | bool load_symtab_id); 14 | 15 | void fix_external_symbols(ASR::TranslationUnit_t &unit, 16 | SymbolTable &external_symtab); 17 | } // namespace LCompilers 18 | 19 | #endif // LIBASR_SERIALIZATION_H 20 | -------------------------------------------------------------------------------- /src/libasr/stacktrace.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_STACKTRACE_H 2 | #define LFORTRAN_STACKTRACE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace LCompilers { 9 | 10 | /* Returns the current stacktrace as a string. 11 | * 12 | * impl_stacktrace_depth ... The stacktrace depth to remove from the stacktrace 13 | * printout to avoid showing users implementation functions in the 14 | * stacktrace. 15 | */ 16 | std::string get_stacktrace(int impl_stacktrace_depth=0); 17 | 18 | // Prints the current stacktrace to stdout. 19 | void show_stacktrace(); 20 | 21 | // Prints the current stacktrace to stdout on segfault. 22 | void print_stack_on_segfault(); 23 | 24 | // Path to the binary executable 25 | extern std::string binary_executable_path; 26 | 27 | struct StacktraceItem 28 | { 29 | // Always found 30 | uintptr_t pc; 31 | 32 | // The following two are either both found, or not found 33 | uintptr_t local_pc=0; // 0 if not found 34 | std::string binary_filename; // "" if not found 35 | 36 | // This can be found or not 37 | std::string function_name; // "" if not found 38 | 39 | // The following two are either both found, or not found 40 | std::string source_filename; // "" if not found 41 | int line_number=-1; // -1 if not found 42 | }; 43 | 44 | // Returns the stacktrace, fills in the `pc` member 45 | std::vector get_stacktrace_addresses(); 46 | 47 | // Fills in the `local_pc` and `binary_filename` members 48 | void get_local_addresses(std::vector &d); 49 | 50 | // Fills in the `function_name` if available, and if so, also fills in 51 | // `source_filename` and `line_number` if available 52 | void get_local_info(std::vector &d); 53 | 54 | // Converts the information stored in `d` into a string 55 | std::string stacktrace2str(const std::vector &d, 56 | int skip); 57 | 58 | // Returns line number information from address 59 | void address_to_line_number(const std::vector &filenames, 60 | const std::vector &addresses, 61 | uintptr_t address, 62 | std::string &filename, 63 | int &line_number); 64 | 65 | std::string error_stacktrace(const std::vector &stacktrace); 66 | 67 | } // namespace LCompilers 68 | 69 | #endif // LFORTRAN_STACKTRACE_H 70 | -------------------------------------------------------------------------------- /src/libasr/string_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef LFORTRAN_STRING_UTILS_H 2 | #define LFORTRAN_STRING_UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace LCompilers { 12 | 13 | 14 | bool startswith(const std::string &s, const std::string &e); 15 | bool endswith(const std::string &s, const std::string &e); 16 | std::string to_lower(const std::string &s); 17 | std::vector string_split(const std::string &s, const std::string &split_string); 18 | std::vector split(const std::string &s); 19 | std::string join(const std::string j, const std::vector &v); 20 | std::vector slice(const std::vector &v, 21 | int start=0, int end=-1); 22 | char *s2c(Allocator &al, const std::string &s); 23 | 24 | // Replaces all occurrences of `regex` (a regular expression, must escape 25 | // special characters) with `replace` 26 | std::string replace(const std::string &s, 27 | const std::string ®ex, const std::string &replace); 28 | 29 | std::string read_file(const std::string &filename); 30 | 31 | // Returns the parent path to the given path 32 | std::string parent_path(const std::string &path); 33 | // Returns true if the path is relative 34 | bool is_relative_path(const std::string &path); 35 | // Joins paths (paths can be empty) 36 | std::string join_paths(const std::vector &paths); 37 | 38 | // Escapes special characters from the given string 39 | // using C style escaping 40 | std::string str_escape_c(const std::string &s); 41 | char* str_unescape_c(Allocator &al, LCompilers::Str &s); 42 | 43 | // Escapes double quote characters from the given string 44 | // given string must be enclosed in double quotes 45 | std::string str_escape_fortran_double_quote(const std::string &s); 46 | char* str_unescape_fortran(Allocator &al, LCompilers::Str &s, char ch); 47 | 48 | } // namespace LCompilers 49 | 50 | #endif // LFORTRAN_STRING_UTILS_H 51 | -------------------------------------------------------------------------------- /src/runtime/legacy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SRC 2 | ../../../src/libasr/runtime/lfortran_intrinsics.c 3 | ) 4 | add_library(lc_runtime SHARED ${SRC}) 5 | target_include_directories(lc_runtime BEFORE PUBLIC ${libasr_SOURCE_DIR}/..) 6 | target_include_directories(lc_runtime BEFORE PUBLIC ${libasr_BINARY_DIR}/..) 7 | set_target_properties(lc_runtime PROPERTIES 8 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../$<0:> 9 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../$<0:> 10 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../$<0:>) 11 | add_library(lc_runtime_static STATIC ${SRC}) 12 | target_include_directories(lc_runtime_static BEFORE PUBLIC ${libasr_SOURCE_DIR}/..) 13 | target_include_directories(lc_runtime_static BEFORE PUBLIC ${libasr_BINARY_DIR}/..) 14 | set_target_properties(lc_runtime_static PROPERTIES 15 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../$<0:> 16 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../$<0:> 17 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../$<0:>) 18 | install(TARGETS lc_runtime lc_runtime_static 19 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 20 | ARCHIVE DESTINATION share/lc/lib 21 | LIBRARY DESTINATION share/lc/lib 22 | ) 23 | 24 | # Install the header 25 | install( 26 | FILES ../../../src/libasr/runtime/lfortran_intrinsics.h 27 | DESTINATION share/lc/lib/impure 28 | ) 29 | -------------------------------------------------------------------------------- /tests/array_01_mdspan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::vector arr1_data = {1.0, 2.0, 3.0, 2.0, 5.0, 7.0, 2.0, 5.0, 7.0}; 7 | 8 | Kokkos::mdspan> arr1{arr1_data.data(), 3, 3}; 9 | 10 | arr1_data[0] = 4.0; 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/array_02_mdspan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct A { 5 | std::vector arr1_data; 6 | }; 7 | 8 | int main1() { 9 | 10 | std::vector arr2_data = {1.0, 2.0, 3.0, 2.0, 5.0, 7.0, 2.0, 5.0, 7.0}; 11 | std::vector arr3_data = {1.0, 2.0, 3.0, 2.0, 5.0, 7.0, 2.0, 5.0, 7.0}; 12 | 13 | Kokkos::mdspan> arr1{arr2_data.data(), 3, 3}; 14 | 15 | arr3_data[0] = 4.0; 16 | arr2_data[0] = 4.0; 17 | 18 | return 0; 19 | } 20 | 21 | int main() { 22 | 23 | struct A aobj; 24 | aobj.arr1_data = {1.0, 2.0, 3.0, 2.0, 5.0, 7.0, 2.0, 5.0, 7.0}; 25 | 26 | Kokkos::mdspan> arr1{aobj.arr1_data.data(), 3, 3}; 27 | 28 | aobj.arr1_data[0] = 4.0; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/array_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "xtensor/xtensor.hpp" 3 | #include "xtensor/xio.hpp" 4 | #include "xtensor/xview.hpp" 5 | 6 | int main() { 7 | 8 | xt::xtensor arr1; /* { // TODO: Uncomment this initializer 9 | {1.0, 2.0, 3.0}, 10 | {2.0, 5.0, 7.0}, 11 | {2.0, 5.0, 7.0}}; */ 12 | 13 | xt::xtensor arr2 {5.0, 6.0, 7.0}; 14 | 15 | // xt::xarray res = xt::view(arr1, 1) + arr2; // TODO: Uncomment this statement 16 | std::cout << arr2; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /tests/expr2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int x; 5 | x = (2+3)*5; 6 | printf("%d\n", x); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/parse_comments_01.cpp: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | // #pragma clang diagnostic push 4 | // #pragma clang diagnostic ignored "-Wunused-variable" 5 | 6 | int a; 7 | 8 | // #pragma clang diagnostic pop 9 | 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /tests/reference/asr-array_01-080be05.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-array_01-080be05", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/../integration_tests/array_01.cpp", 5 | "infile_hash": "deb860e61919d1bd2fbc7abeeed41124193f4284de0838d4ba94fa09", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "asr-array_01-080be05.stdout", 9 | "stdout_hash": "a278a5b349fcb27e56da16acb92d7fb7762161bea01c804292663f3c", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/asr-array_01_mdspan-3a0babe.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-array_01_mdspan-3a0babe", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/array_01_mdspan.cpp", 5 | "infile_hash": "89f0c42a5270d3e994901c745aeb9d6b6d005eb466f53abc3c6b0684", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": null, 9 | "stdout_hash": null, 10 | "stderr": "asr-array_01_mdspan-3a0babe.stderr", 11 | "stderr_hash": "75fae36610809dcd01894bb09490f3b174e656cf490f47aa38aa5caf", 12 | "returncode": 1 13 | } -------------------------------------------------------------------------------- /tests/reference/asr-array_01_mdspan-3a0babe.stderr: -------------------------------------------------------------------------------- 1 | arr1_data is marked as read only. 2 | -------------------------------------------------------------------------------- /tests/reference/asr-array_02-ec70729.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-array_02-ec70729", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/../integration_tests/array_02.cpp", 5 | "infile_hash": "cb968d294be0d86c0f49b3364b7a3aa45b53edcc59349301d5f298ed", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "asr-array_02-ec70729.stdout", 9 | "stdout_hash": "d921e30af93bdc79cf404be91285a2dd80d501ce3e9e1bc46b4347b9", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/asr-array_02_mdspan-a54a3c5.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-array_02_mdspan-a54a3c5", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/array_02_mdspan.cpp", 5 | "infile_hash": "0a58aca0631849d0d9f53e91255e409d79d6e8df0db2ce820f0f5d15", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": null, 9 | "stdout_hash": null, 10 | "stderr": "asr-array_02_mdspan-a54a3c5.stderr", 11 | "stderr_hash": "c335fe2f02049228933225c455954d7fb45ed1e5b318fafe53932c96", 12 | "returncode": 1 13 | } -------------------------------------------------------------------------------- /tests/reference/asr-array_02_mdspan-a54a3c5.stderr: -------------------------------------------------------------------------------- 1 | arr2_data is marked as read only. 2 | -------------------------------------------------------------------------------- /tests/reference/asr-array_04-f95b8eb.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-array_04-f95b8eb", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/../integration_tests/array_04.cpp", 5 | "infile_hash": "86bab3bcf300c07e9861e92ce21215829ae2893db1d378776b8ab332", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "asr-array_04-f95b8eb.stdout", 9 | "stdout_hash": "b63d1dcba8f9628e897f64e5ed5f57df9da1c398131da94d0a722bee", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/asr-expr2-dda5523.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-expr2-dda5523", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/expr2.c", 5 | "infile_hash": "11cb114715d67a4763454167abc900089b2119ecf18a980d18a30322", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "asr-expr2-dda5523.stdout", 9 | "stdout_hash": "1e95da0bf9445357bbc5cb0d0d3eef514631cf16a74c8d5f3b5f80ef", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/asr-test-5bdab26.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "asr-test-5bdab26", 3 | "cmd": "lc --show-asr --no-color {infile} -o {outfile}", 4 | "infile": "tests/test.cpp", 5 | "infile_hash": "9e5ef4c37b7e9e1f13f0082ce65459c1e596430887537eb8fd656b77", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "asr-test-5bdab26.stdout", 9 | "stdout_hash": "1bc70975fa9dbd6ac3d26f7397f90eab990cfcf0c31fef3597b7257a", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/c-expr2-6f28c3e.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "c-expr2-6f28c3e", 3 | "cmd": "lc --no-color --show-c {infile}", 4 | "infile": "tests/expr2.c", 5 | "infile_hash": "11cb114715d67a4763454167abc900089b2119ecf18a980d18a30322", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "c-expr2-6f28c3e.stdout", 9 | "stdout_hash": "f5e0bbc80b7b062e04b4e1ca71389d0e84393c3e679032648e797ce9", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/c-expr2-6f28c3e.stdout: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int32_t _xx_lcompilers_changed_main_xx(); 10 | 11 | 12 | 13 | // Implementations 14 | int32_t _xx_lcompilers_changed_main_xx() 15 | { 16 | int32_t __return_var; 17 | int32_t x; 18 | x = (2 + 3)*5; 19 | printf("%d\n", x); 20 | __return_var = 0; 21 | return __return_var; 22 | } 23 | 24 | int main(int argc, char* argv[]) 25 | { 26 | _lpython_set_argv(argc, argv); 27 | int32_t exit_code; 28 | exit_code = _xx_lcompilers_changed_main_xx(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /tests/reference/c-test-ec3a81c.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "c-test-ec3a81c", 3 | "cmd": "lc --no-color --show-c {infile}", 4 | "infile": "tests/test.cpp", 5 | "infile_hash": "9e5ef4c37b7e9e1f13f0082ce65459c1e596430887537eb8fd656b77", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "c-test-ec3a81c.stdout", 9 | "stdout_hash": "3ed031709ad9bea806c48af8882967d8d8b639458614dd93129ba6eb", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/c-test-ec3a81c.stdout: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int32_t f(int32_t *x); 10 | 11 | 12 | 13 | // Implementations 14 | int32_t f(int32_t *x) 15 | { 16 | int32_t __return_var; 17 | int32_t result; 18 | result = (*x)/42; 19 | __return_var = result; 20 | return __return_var; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/reference/cpp-expr2-d2bf1c6.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "cpp-expr2-d2bf1c6", 3 | "cmd": "lc --no-color --show-cpp {infile}", 4 | "infile": "tests/expr2.c", 5 | "infile_hash": "11cb114715d67a4763454167abc900089b2119ecf18a980d18a30322", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "cpp-expr2-d2bf1c6.stdout", 9 | "stdout_hash": "8d4619b93ad4f0abe2863dad83e5f5471f9d17d1866f31213d84f3a7", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/cpp-expr2-d2bf1c6.stdout: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | Kokkos::View from_std_vector(const std::vector &v) 12 | { 13 | Kokkos::View r("r", v.size()); 14 | for (size_t i=0; i < v.size(); i++) { 15 | r(i) = v[i]; 16 | } 17 | return r; 18 | } 19 | 20 | // Forward declarations 21 | int32_t _xx_lcompilers_changed_main_xx(); 22 | namespace { 23 | } 24 | 25 | // Implementations 26 | int32_t _xx_lcompilers_changed_main_xx() 27 | { 28 | int32_t __return_var; 29 | int32_t x; 30 | x = (2 + 3)*5; 31 | std::cout << x << std::endl; 32 | __return_var = 0; 33 | return __return_var; 34 | } 35 | 36 | namespace { 37 | 38 | void main2() { 39 | int32_t exit_code; 40 | exit_code = _xx_lcompilers_changed_main_xx(); 41 | } 42 | 43 | } 44 | int main(int argc, char* argv[]) 45 | { 46 | Kokkos::initialize(argc, argv); 47 | main2(); 48 | Kokkos::finalize(); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tests/reference/cpp-test-660bf28.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "cpp-test-660bf28", 3 | "cmd": "lc --no-color --show-cpp {infile}", 4 | "infile": "tests/test.cpp", 5 | "infile_hash": "9e5ef4c37b7e9e1f13f0082ce65459c1e596430887537eb8fd656b77", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "cpp-test-660bf28.stdout", 9 | "stdout_hash": "27108a8e13274f0b14756c71f802f468b65e40d511b3a72cc9e30df8", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/cpp-test-660bf28.stdout: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | Kokkos::View from_std_vector(const std::vector &v) 12 | { 13 | Kokkos::View r("r", v.size()); 14 | for (size_t i=0; i < v.size(); i++) { 15 | r(i) = v[i]; 16 | } 17 | return r; 18 | } 19 | 20 | // Forward declarations 21 | int32_t f(int32_t &x); 22 | 23 | // Implementations 24 | int32_t f(int32_t &x) 25 | { 26 | int32_t __return_var; 27 | int32_t result; 28 | result = x/42; 29 | __return_var = result; 30 | return __return_var; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /tests/reference/fortran-expr2-98fb1e2.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "fortran-expr2-98fb1e2", 3 | "cmd": "lc --no-color --show-fortran {infile}", 4 | "infile": "tests/expr2.c", 5 | "infile_hash": "11cb114715d67a4763454167abc900089b2119ecf18a980d18a30322", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "fortran-expr2-98fb1e2.stdout", 9 | "stdout_hash": "79877dd33c7f4304ceefe7e697e1d6840b3e72e9b5e84cf470b747c9", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/fortran-expr2-98fb1e2.stdout: -------------------------------------------------------------------------------- 1 | program main_program 2 | implicit none 3 | integer(4) :: exit_code 4 | exit_code = main() 5 | 6 | contains 7 | 8 | integer(4) function main() result(__return_var) 9 | integer(4) :: x 10 | x = (2 + 3)*5 11 | print *, x 12 | __return_var = 0 13 | return 14 | end function main 15 | 16 | end program main_program 17 | -------------------------------------------------------------------------------- /tests/reference/fortran-test-a055f99.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "fortran-test-a055f99", 3 | "cmd": "lc --no-color --show-fortran {infile}", 4 | "infile": "tests/test.cpp", 5 | "infile_hash": "9e5ef4c37b7e9e1f13f0082ce65459c1e596430887537eb8fd656b77", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": null, 9 | "stdout_hash": null, 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/fortran-test-a055f99.stdout: -------------------------------------------------------------------------------- 1 | integer(4) function f(x) result(__return_var) 2 | integer(4) :: result 3 | integer(4), intent(inout) :: x 4 | result = x/42 5 | __return_var = result 6 | return 7 | end function f 8 | -------------------------------------------------------------------------------- /tests/reference/llvm-expr2-94e7c35.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "llvm-expr2-94e7c35", 3 | "cmd": "lc --no-color --show-llvm {infile} -o {outfile}", 4 | "infile": "tests/expr2.c", 5 | "infile_hash": "11cb114715d67a4763454167abc900089b2119ecf18a980d18a30322", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "llvm-expr2-94e7c35.stdout", 9 | "stdout_hash": "f84e616de338d7da42865b2bea66bed96a8bbb448f7d8f7eff385f09", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/llvm-expr2-94e7c35.stdout: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'LFortran' 2 | source_filename = "LFortran" 3 | 4 | @0 = private unnamed_addr constant [2 x i8] c" \00", align 1 5 | @1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 6 | @2 = private unnamed_addr constant [5 x i8] c"%d%s\00", align 1 7 | 8 | define i32 @_xx_lcompilers_changed_main_xx() { 9 | .entry: 10 | %__return_var = alloca i32, align 4 11 | %x = alloca i32, align 4 12 | store i32 25, i32* %x, align 4 13 | %0 = load i32, i32* %x, align 4 14 | call void (i8*, ...) @_lfortran_printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @2, i32 0, i32 0), i32 %0, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @1, i32 0, i32 0)) 15 | store i32 0, i32* %__return_var, align 4 16 | br label %return 17 | 18 | unreachable_after_return: ; No predecessors! 19 | br label %return 20 | 21 | return: ; preds = %unreachable_after_return, %.entry 22 | %1 = load i32, i32* %__return_var, align 4 23 | ret i32 %1 24 | } 25 | 26 | declare void @_lfortran_printf(i8*, ...) 27 | 28 | define i32 @main(i32 %0, i8** %1) { 29 | .entry: 30 | call void @_lpython_call_initial_functions(i32 %0, i8** %1) 31 | %exit_code = alloca i32, align 4 32 | %2 = call i32 @_xx_lcompilers_changed_main_xx() 33 | store i32 %2, i32* %exit_code, align 4 34 | ret i32 0 35 | } 36 | 37 | declare void @_lpython_call_initial_functions(i32, i8**) 38 | -------------------------------------------------------------------------------- /tests/reference/llvm-test-63615c0.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "llvm-test-63615c0", 3 | "cmd": "lc --no-color --show-llvm {infile} -o {outfile}", 4 | "infile": "tests/test.cpp", 5 | "infile_hash": "9e5ef4c37b7e9e1f13f0082ce65459c1e596430887537eb8fd656b77", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "llvm-test-63615c0.stdout", 9 | "stdout_hash": "693feb9b391bb484b8222d405bef48b74ca2ab345a8bb0bfcf1f78f5", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/llvm-test-63615c0.stdout: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'LFortran' 2 | source_filename = "LFortran" 3 | 4 | define i32 @f(i32* %x) { 5 | .entry: 6 | %__return_var = alloca i32, align 4 7 | %result = alloca i32, align 4 8 | %0 = load i32, i32* %x, align 4 9 | %1 = sdiv i32 %0, 42 10 | store i32 %1, i32* %result, align 4 11 | %2 = load i32, i32* %result, align 4 12 | store i32 %2, i32* %__return_var, align 4 13 | br label %return 14 | 15 | unreachable_after_return: ; No predecessors! 16 | br label %return 17 | 18 | return: ; preds = %unreachable_after_return, %.entry 19 | %3 = load i32, i32* %__return_var, align 4 20 | ret i32 %3 21 | } 22 | -------------------------------------------------------------------------------- /tests/reference/wat-expr2-e3ba463.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "wat-expr2-e3ba463", 3 | "cmd": "lc --no-color --show-wat {infile}", 4 | "infile": "tests/expr2.c", 5 | "infile_hash": "11cb114715d67a4763454167abc900089b2119ecf18a980d18a30322", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "wat-expr2-e3ba463.stdout", 9 | "stdout_hash": "12b22e184734cc4d1a8037b52a2f5b1675b205586a5b9ae5692b1358", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/wat-test-b9b1dc9.json: -------------------------------------------------------------------------------- 1 | { 2 | "basename": "wat-test-b9b1dc9", 3 | "cmd": "lc --no-color --show-wat {infile}", 4 | "infile": "tests/test.cpp", 5 | "infile_hash": "9e5ef4c37b7e9e1f13f0082ce65459c1e596430887537eb8fd656b77", 6 | "outfile": null, 7 | "outfile_hash": null, 8 | "stdout": "wat-test-b9b1dc9.stdout", 9 | "stdout_hash": "b66a0896be5ba2e503e367339bf62c315f3c7fc8eb170034c78e6fb6", 10 | "stderr": null, 11 | "stderr_hash": null, 12 | "returncode": 0 13 | } -------------------------------------------------------------------------------- /tests/reference/wat-test-b9b1dc9.stdout: -------------------------------------------------------------------------------- 1 | (module 2 | (type (;0;) (func (param i32) (result))) 3 | (type (;1;) (func (param i32 i32 i32 i32) (result i32))) 4 | (type (;2;) (func (param i32) (result i32))) 5 | (import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0))) 6 | (import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1))) 7 | (global $0 (mut i32) (i32.const 0)) 8 | (global $1 (mut i32) (i32.const 0)) 9 | (global $2 (mut i64) (i64.const 0)) 10 | (global $3 (mut f32) (f32.const 0.000000)) 11 | (global $4 (mut f32) (f32.const 0.000000)) 12 | (global $5 (mut f64) (f64.const 0.000000)) 13 | (global $6 (mut f64) (f64.const 0.000000)) 14 | (func $2 (type 2) (param i32) (result i32) 15 | (local i32 i32) 16 | local.get 0 17 | i32.const 42 18 | i32.div_s 19 | local.set 2 20 | local.get 2 21 | local.set 1 22 | local.get 1 23 | return 24 | ) 25 | (memory (;0;) 1000 1000) 26 | (export "memory" (memory 0)) 27 | (export "f" (func 2)) 28 | (data (;0;) (i32.const 4) "\0c\00\00\00\01\00\00\00") 29 | (data (;1;) (i32.const 12) " ") 30 | (data (;2;) (i32.const 16) "\18\00\00\00\01\00\00\00") 31 | (data (;3;) (i32.const 24) "\n ") 32 | (data (;4;) (i32.const 28) "\24\00\00\00\01\00\00\00") 33 | (data (;5;) (i32.const 36) "- ") 34 | (data (;6;) (i32.const 40) "\30\00\00\00\01\00\00\00") 35 | (data (;7;) (i32.const 48) ". ") 36 | (data (;8;) (i32.const 52) "\3c\00\00\00\01\00\00\00") 37 | (data (;9;) (i32.const 60) "( ") 38 | (data (;10;) (i32.const 64) "\48\00\00\00\01\00\00\00") 39 | (data (;11;) (i32.const 72) ") ") 40 | (data (;12;) (i32.const 76) "\54\00\00\00\01\00\00\00") 41 | (data (;13;) (i32.const 84) ", ") 42 | (data (;14;) (i32.const 88) "\60\00\00\00\01\00\00\00") 43 | (data (;15;) (i32.const 96) "0 ") 44 | (data (;16;) (i32.const 100) "\6c\00\00\00\01\00\00\00") 45 | (data (;17;) (i32.const 108) "1 ") 46 | (data (;18;) (i32.const 112) "\78\00\00\00\01\00\00\00") 47 | (data (;19;) (i32.const 120) "2 ") 48 | (data (;20;) (i32.const 124) "\84\00\00\00\01\00\00\00") 49 | (data (;21;) (i32.const 132) "3 ") 50 | (data (;22;) (i32.const 136) "\90\00\00\00\01\00\00\00") 51 | (data (;23;) (i32.const 144) "4 ") 52 | (data (;24;) (i32.const 148) "\9c\00\00\00\01\00\00\00") 53 | (data (;25;) (i32.const 156) "5 ") 54 | (data (;26;) (i32.const 160) "\a8\00\00\00\01\00\00\00") 55 | (data (;27;) (i32.const 168) "6 ") 56 | (data (;28;) (i32.const 172) "\b4\00\00\00\01\00\00\00") 57 | (data (;29;) (i32.const 180) "7 ") 58 | (data (;30;) (i32.const 184) "\c0\00\00\00\01\00\00\00") 59 | (data (;31;) (i32.const 192) "8 ") 60 | (data (;32;) (i32.const 196) "\cc\00\00\00\01\00\00\00") 61 | (data (;33;) (i32.const 204) "9 ") 62 | ) 63 | -------------------------------------------------------------------------------- /tests/span_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int arr[] = { 1, 2, 3, 4, 5 }; 8 | 9 | std::span span_arr(arr); 10 | 11 | for (const auto& num : span_arr) { 12 | std::cout << num << " "; 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tests/test.cpp: -------------------------------------------------------------------------------- 1 | int f(int x) { 2 | int result = (x / 42); 3 | return result; 4 | } 5 | -------------------------------------------------------------------------------- /tests/tests.toml: -------------------------------------------------------------------------------- 1 | # Possible tests: 2 | # ast ... run the Parser and output AST, compare against reference version 3 | # asr ... run the Semantics and output ASR, compare against reference version 4 | 5 | # tests 6 | 7 | [[test]] 8 | filename = "test.cpp" 9 | asr = true 10 | wat = true 11 | c = true 12 | cpp = true 13 | llvm = true 14 | fortran = true 15 | 16 | [[test]] 17 | filename = "expr2.c" 18 | asr = true 19 | wat = true 20 | c = true 21 | cpp = true 22 | llvm = true 23 | fortran = true 24 | 25 | [[test]] 26 | filename = "array_01_mdspan.cpp" 27 | asr = true 28 | 29 | [[test]] 30 | filename = "array_02_mdspan.cpp" 31 | asr = true 32 | 33 | [[test]] 34 | filename = "../integration_tests/array_01.cpp" 35 | asr = true 36 | 37 | [[test]] 38 | filename = "../integration_tests/array_02.cpp" 39 | asr = true 40 | 41 | [[test]] 42 | filename = "../integration_tests/array_04.cpp" 43 | asr = true 44 | --------------------------------------------------------------------------------