├── .gitignore ├── .travis.yml.off ├── CMakeLists.txt ├── LICENSE.TXT ├── README.md ├── cmake └── impala-config.cmake.in ├── doxyfile ├── src ├── CMakeLists.txt ├── impala │ ├── CMakeLists.txt │ ├── args.h │ ├── ast.cpp │ ├── ast.h │ ├── ast_stream.cpp │ ├── cgen.cpp │ ├── cgen.h │ ├── emit.cpp │ ├── impala.cpp │ ├── impala.h │ ├── lexer.cpp │ ├── lexer.h │ ├── main.cpp │ ├── parser.cpp │ ├── sema │ │ ├── infersema.cpp │ │ ├── namesema.cpp │ │ ├── type.cpp │ │ ├── type.h │ │ ├── type_table.h │ │ └── typesema.cpp │ ├── token.cpp │ ├── token.h │ └── tokenlist.h └── intrinsicgen │ ├── CMakeLists.txt │ └── main.cpp └── test ├── CMakeLists.txt ├── blocked_loop2.impala ├── codegen ├── ackermann.impala ├── aliasing.impala ├── alloc_definite_array.impala ├── allset_bug.impala ├── and.impala ├── anonymous.impala ├── array.impala ├── benchmarks │ ├── aobench.impala │ ├── aobench.out │ ├── fannkuch.impala │ ├── fannkuch.out │ ├── fasta.impala │ ├── fasta.out │ ├── mandelbrot.impala │ ├── mandelbrot.out │ ├── meteor.impala │ ├── meteor.out │ ├── nbody.impala │ ├── nbody.out │ ├── pidigits.impala │ ├── pidigits.out │ ├── regex.impala │ ├── regex.in │ ├── regex.out │ ├── reverse.impala │ ├── reverse.in │ ├── reverse.out │ ├── spectral.impala │ └── spectral.out ├── bind_ret_inner_fn.impala ├── bitcast.impala ├── bool_to_signed.impala ├── bottom.impala ├── break.impala ├── cast.impala ├── cfa_out.impala ├── char.impala ├── complex_for.impala ├── conditionals.impala ├── constant_ordering_bug.impala ├── continue.impala ├── conversion_trait.impala ├── cur_bb_bug.impala ├── diderot.impala ├── empty_string.impala ├── empty_string.out ├── endless_mangling.impala ├── endless_pe.impala ├── fac_double.impala ├── fac_float.impala ├── fac_int.impala ├── fac_nest.impala ├── fac_rec.impala ├── fac_tail.impala ├── fib.impala ├── fieldexpr.impala ├── float_literal.impala ├── fold.impala ├── generic_get.impala ├── generic_while.impala ├── growing_stack.impala ├── hello_world.impala ├── hello_world.out ├── if_return_bug.impala ├── if_stmt_expr.impala ├── inline_asm │ └── x86_64 │ │ ├── asm_atomic_decrement.impala │ │ ├── asm_simple_1.impala │ │ ├── asm_simple_2.impala │ │ ├── asm_simple_3.impala │ │ ├── asm_strcpy.impala │ │ ├── asm_strcpy.out │ │ ├── asm_syscall.impala │ │ └── asm_syscall.out ├── labeled_break.impala ├── lambda_assert.impala ├── land.impala ├── ldg.impala ├── lea_bug.impala ├── lvalue_struct.impala ├── match.impala ├── match_color.impala ├── mem2reg_bug.impala ├── mem2reg_bug2.impala ├── mod.impala ├── mono_range.impala ├── mutable_load.impala ├── nested_functions.impala ├── nullptr.impala ├── nullptr.out ├── or.impala ├── parallel.impala ├── param_elimination_bug.impala ├── partial_eval_bug.impala ├── poly_id.impala ├── poly_sort.impala ├── poly_sq.impala ├── poly_type_arg.impala ├── power.impala ├── power_half.impala ├── primes.impala ├── primes_for.impala ├── range.impala ├── range_f.impala ├── range_for.impala ├── range_l.impala ├── range_poly.impala ├── range_unroll.impala ├── ref_array_array_literal.impala ├── ret_assert.impala ├── return_in_lambda.impala ├── return_tuple.impala ├── returning_yield.impala ├── retvoid.impala ├── rvalue_ref.impala ├── select.impala ├── shift.impala ├── shift_bug.impala ├── simd_lea.impala ├── simple.impala ├── sizeof.impala ├── static.impala ├── steensgard.impala ├── string.impala ├── string.out ├── struct.impala ├── struct_arg.impala ├── struct_expr.impala ├── subtype.impala ├── subtyping_struct_expr.impala ├── system_f_problem.impala ├── trait_impls.impala ├── trait_impls.out ├── typeof.impala ├── vcycle.impala ├── void_tailcall.impala ├── while.impala ├── while_fold1.impala ├── while_fold2.impala ├── while_nested.impala ├── while_seq.impala ├── while_true.impala └── zip.impala ├── fix_output.sh ├── partial_eval ├── ackermann.impala ├── array.impala ├── blocked_loop.impala ├── double_loop.impala ├── dynamic_fun.impala ├── logic_operator.impala ├── mut_slot_loops.impala ├── nested.impala ├── nested_loop.impala ├── power.impala ├── range.impala ├── runblock.impala ├── sorting_net_batcher.impala ├── sorting_net_bose_nelson.impala ├── two_loops.impala └── unroll.impala ├── perform.py ├── rtmock.cpp ├── run.py ├── sema ├── negative │ ├── address_of_val_array.out │ ├── anonymous.impala │ ├── anonymous.out │ ├── array_equality.impala │ ├── assign.impala │ ├── assign_no_lvalue.impala │ ├── assign_no_lvalue.out │ ├── bool_literal.impala │ ├── char.impala │ ├── char.out │ ├── constrain_check.impala │ ├── constrain_check.out │ ├── cps_call.impala │ ├── cps_call.out │ ├── def_array.impala │ ├── fn_neq1.impala │ ├── fn_neq1.out │ ├── if01.impala │ ├── if01.out │ ├── impl_bounds.impala │ ├── impl_bounds.out │ ├── incorrect_param_types.impala │ ├── incorrect_param_types.out │ ├── indefinite_array.impala │ ├── indefinite_array.out │ ├── int_literal.impala │ ├── lazy_analysis1.impala │ ├── lazy_analysis2.impala │ ├── lazy_analysis2.out │ ├── literal_overflow.impala │ ├── literal_overflow.out │ ├── literals.impala │ ├── literals.out │ ├── literals_too_large.impala │ ├── lvalue_inc_dec.impala │ ├── lvalue_inc_dec.out │ ├── methods01.impala │ ├── methods02.impala │ ├── missing_typevar.impala │ ├── missing_typevar.out │ ├── mutual_trait_refs.impala │ ├── mutual_trait_refs.out │ ├── no_ret1.impala │ ├── no_ret1.out │ ├── repeated_definite_array_expr03.impala │ ├── repeated_definite_array_expr03.out │ ├── return1.impala │ ├── return1.out │ ├── return2.impala │ ├── return2.out │ ├── scoping1.impala │ ├── scoping1.out │ ├── scoping2.impala │ ├── scoping2.out │ ├── simd.impala │ ├── simd.out │ ├── static.impala │ ├── string.impala │ ├── string.out │ ├── struct01.impala │ ├── struct02.impala │ ├── struct03.impala │ ├── struct04.impala │ ├── struct05.impala │ ├── struct06.impala │ ├── struct07.impala │ ├── struct08.impala │ ├── struct08.out │ ├── struct09.impala │ ├── struct09.out │ ├── struct_equality.impala │ ├── struct_names.impala │ ├── struct_names.out │ ├── subtyping1.impala │ ├── subtyping1.out │ ├── subtyping2.impala │ ├── subtyping2.out │ ├── subtyping3_ptr.impala │ ├── subtyping3_ptr.out │ ├── subtyping4_array.impala │ ├── subtyping4_array.out │ ├── subtyping5.impala │ ├── subtyping5.out │ ├── super_traits1.impala │ ├── super_traits1.out │ ├── super_traits2.impala │ ├── super_traits2.out │ ├── super_traits3.impala │ ├── super_traits3.out │ ├── super_traits4.impala │ ├── trait_impls1.impala │ ├── trait_impls2.impala │ ├── trait_impls3.impala │ ├── trait_impls4.impala │ ├── trait_impls5.impala │ ├── trait_impls5.out │ ├── trait_impls6.impala │ ├── trait_impls6.out │ ├── unreachable.impala │ ├── unreachable.out │ ├── while.impala │ ├── wrong_arg_num1.impala │ ├── wrong_arg_num1.out │ ├── wrong_arg_num2.impala │ ├── wrong_arg_num3.impala │ ├── wrong_arg_num3.out │ ├── wrong_arg_num4.impala │ ├── wrong_arg_num5.impala │ ├── wrong_arg_num5.out │ ├── wrong_arg_type.impala │ ├── wrong_condition_type.impala │ ├── wrong_condition_type.out │ ├── wrong_return.impala │ ├── wrong_return.out │ ├── wrong_return1.impala │ └── wrong_return2.impala └── positive │ ├── address01.impala │ ├── address02.impala │ ├── array_access01.impala │ ├── block.impala │ ├── bound_checking1.impala │ ├── bound_checking2.impala │ ├── bound_checking3.impala │ ├── bound_checking4.impala │ ├── break.impala │ ├── call_simple.impala │ ├── cast.impala │ ├── complex_fn_type1.impala │ ├── continuation.impala │ ├── cross_struct.impala │ ├── double_continue.impala │ ├── elseif.impala │ ├── empty.impala │ ├── extern.impala │ ├── field_infer.impala │ ├── float.impala │ ├── fn_equal1.impala │ ├── fn_expr.impala │ ├── if01.impala │ ├── if02.impala │ ├── if03.impala │ ├── if04.impala │ ├── if05.impala │ ├── if06.impala │ ├── if07.impala │ ├── if08.impala │ ├── if09.impala │ ├── if10.impala │ ├── impl_after_usage1.impala │ ├── impl_after_usage2.impala │ ├── int_is_int32.impala │ ├── lambda.impala │ ├── lazy_analysis1.impala │ ├── let1.impala │ ├── let2.impala │ ├── let3.impala │ ├── literals.impala │ ├── literals1.impala │ ├── literals2.impala │ ├── literals3.impala │ ├── literals4.impala │ ├── map.impala │ ├── methods1.impala │ ├── methods2.impala │ ├── methods3.impala │ ├── methods4.impala │ ├── methods5.impala │ ├── methods6.impala │ ├── methods7.impala │ ├── methods8.impala │ ├── mutual_recursion1.impala │ ├── mutual_recursion2.impala │ ├── nested_lambdas.impala │ ├── noret.impala │ ├── not.impala │ ├── ptr.impala │ ├── range.impala │ ├── repeated_definite_array_expr01.impala │ ├── repeated_definite_array_expr02.impala │ ├── return1.impala │ ├── return2.impala │ ├── return3.impala │ ├── return4.impala │ ├── return5.impala │ ├── return6.impala │ ├── retvoid.impala │ ├── scoping1.impala │ ├── simd.impala │ ├── struct01.impala │ ├── struct02.impala │ ├── struct03.impala │ ├── struct04.impala │ ├── struct05.impala │ ├── struct_lambda01.impala │ ├── struct_lambda02.impala │ ├── struct_typedef01.impala │ ├── struct_typedef02.impala │ ├── subtyping1.impala │ ├── subtyping2_ptr.impala │ ├── subtyping3_array.impala │ ├── subtyping3_rec.impala │ ├── subtyping4.impala │ ├── subtyping5.impala │ ├── subtyping6_rec.impala │ ├── subtyping_traits1.impala │ ├── subtyping_traits2.impala │ ├── super_traits1.impala │ ├── super_traits2.impala │ ├── super_traits3.impala │ ├── super_traits4.impala │ ├── super_traits5.impala │ ├── super_traits6.impala │ ├── trait_def_after_usage.impala │ ├── trait_impls1.impala │ ├── trait_impls2.impala │ ├── tuples01.impala │ ├── tuples02.impala │ ├── tuples03.impala │ ├── typedef.impala │ ├── typedef_struct.impala │ ├── typevar_instantiation1.impala │ ├── typevar_instantiation10.impala │ ├── typevar_instantiation11.impala │ ├── typevar_instantiation12.impala │ ├── typevar_instantiation2.impala │ ├── typevar_instantiation3.impala │ ├── typevar_instantiation4.impala │ ├── typevar_instantiation5.impala │ ├── typevar_instantiation6.impala │ ├── typevar_instantiation7.impala │ ├── typevar_instantiation8.impala │ ├── typevar_instantiation9.impala │ ├── typevar_instantiation_with_subtyping.impala │ ├── typevar_instantiation_with_subtyping2.impala │ └── unary_minus.impala └── type_inference ├── negative ├── map1.impala ├── map1.output ├── map2.impala ├── map2.output ├── subtype_fnargs1.impala ├── subtype_fnargs1.output ├── type_args1.impala ├── type_args1.output ├── type_args10.impala ├── type_args10.output ├── type_args2.impala ├── type_args2.output ├── type_args3.impala ├── type_args3.output ├── type_args4.impala ├── type_args4.output ├── type_args5.impala ├── type_args5.output ├── type_args6.impala ├── type_args6.output ├── type_args7.impala ├── type_args7.output ├── type_args8.impala ├── type_args8.output ├── type_args9.impala ├── type_args9.output ├── type_struct.impala ├── unused_typevar1.impala └── unused_typevar1.output └── positive ├── bottom_up1.impala ├── bottom_up1.output ├── fixed_point_iteration01.impala ├── fixed_point_iteration01.output ├── hard1.impala ├── hard1.output ├── hard2.impala ├── hard3.impala ├── hard3.output ├── id_id.impala ├── id_id.output ├── id_twice.impala ├── id_twice.output ├── if01.impala ├── if01.output ├── if02.impala ├── if02.output ├── if03.impala ├── if03.output ├── let1.impala ├── let1.output ├── map.impala ├── param_inference1.impala ├── param_inference1.output ├── param_inference2.impala ├── param_inference2.output ├── param_inference3.impala ├── param_inference3.output ├── param_inference4.impala ├── param_inference4.output ├── poly_pass1.impala ├── range.impala ├── range.output ├── ret_lambda.impala ├── return_lambda.impala ├── return_lambda.output ├── struct_ptr.impala ├── struct_ptr.output ├── struct_typedef01.impala ├── struct_typedef01.output ├── struct_typedef02.impala ├── struct_typedef02.output ├── structs01.impala ├── structs01.output ├── structs02.impala ├── structs02.output ├── structs03.impala ├── structs03.output ├── subtyping_if1.impala ├── subtyping_if1.output ├── subtyping_if2.impala ├── subtyping_if2.output ├── type_args1.impala ├── type_args1.output ├── type_args10.impala ├── type_args10.ouptut ├── type_args11.impala ├── type_args11.output ├── type_args12.impala ├── type_args12.output ├── type_args13.impala ├── type_args13.output ├── type_args14.impala ├── type_args14.output ├── type_args2.impala ├── type_args2.output ├── type_args3.impala ├── type_args3.output ├── type_args4.impala ├── type_args4.output ├── type_args5.impala ├── type_args5.output ├── type_args6.impala ├── type_args6.output ├── type_args8.impala ├── type_args8.output ├── type_args9.impala ├── type_args9.output ├── type_args_infix01.impala ├── type_args_infix01.output ├── type_args_prefix01.impala ├── type_args_prefix01.output ├── type_args_prefix02.impala ├── type_args_prefix02.output ├── type_args_prefix03.impala ├── type_args_prefix03.output ├── type_args_prefix04.impala ├── type_args_prefix04.output ├── type_args_prefix05.impala ├── type_args_prefix05.output ├── type_args_prefix06.impala ├── type_args_prefix06.output ├── type_args_prefix07.impala └── type_args_prefix07.output /.gitignore: -------------------------------------------------------------------------------- 1 | *.vcg 2 | build* 3 | html 4 | test/config* 5 | test/__pycache__ 6 | -------------------------------------------------------------------------------- /.travis.yml.off: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | sudo: required 4 | dist: trusty 5 | 6 | cache: 7 | - ccache 8 | 9 | install: 10 | - mkdir -p ~/cmake 11 | - mkdir -p ~/work 12 | 13 | - cd ~/work 14 | - git clone --branch=$TRAVIS_BRANCH https://github.com/AnyDSL/anydsl.git 15 | 16 | - cd anydsl 17 | - bash scripts/install_cmake.sh ~/cmake/ 18 | - export PATH=~/cmake/bin:~/work/anydsl/llvm_install/bin:~/work/anydsl/impala/build/bin:$PATH 19 | 20 | - cp config.sh.template config.sh 21 | - sed -i 's/BRANCH:=master/BRANCH:=$TRAVIS_BRANCH/g' config.sh 22 | - sed -i 's/HTTPS:=false/HTTPS:=true/g' config.sh 23 | - sed -i 's/FETCH_LLVM:=false/FETCH_LLVM:=true/g' config.sh 24 | - cat config.sh 25 | 26 | - CXX=/home/travis/work/anydsl/llvm_install/bin/clang++ ./setup.sh 27 | 28 | script: 29 | - cd impala/test/ 30 | - python run_tests.py . 31 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20.0 FATAL_ERROR) 2 | 3 | project(Impala) 4 | 5 | set(PACKAGE_VERSION "0.3.9") 6 | #set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "limited config" FORCE) 7 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS 1) 8 | set(CMAKE_CXX_STANDARD 17) 9 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 10 | 11 | option(BUILD_SHARED_LIBS "Build shared libraries" ON) 12 | 13 | if(CMAKE_BUILD_TYPE STREQUAL "") 14 | set(CMAKE_BUILD_TYPE Debug CACHE STRING "Debug or Release" FORCE) 15 | endif() 16 | 17 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 18 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 19 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 20 | 21 | find_package(Thorin REQUIRED) 22 | 23 | message(STATUS "Using Debug flags: ${CMAKE_CXX_FLAGS_DEBUG}") 24 | message(STATUS "Using Release flags: ${CMAKE_CXX_FLAGS_RELEASE}") 25 | if(DEFINED CMAKE_BUILD_TYPE) 26 | message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") 27 | endif() 28 | 29 | set(Impala_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 30 | 31 | add_subdirectory(src) 32 | 33 | export(TARGETS libimpala impala FILE ${CMAKE_BINARY_DIR}/share/anydsl/cmake/impala-exports.cmake) 34 | configure_file(cmake/impala-config.cmake.in ${CMAKE_BINARY_DIR}/share/anydsl/cmake/impala-config.cmake @ONLY) 35 | 36 | if(BUILD_TESTING) 37 | enable_testing() 38 | add_subdirectory(test) 39 | endif() 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Impala 2 | An imperative and functional programming language. 3 | 4 | ## Build Instructions 5 | 6 | See [Build Instructions](https://anydsl.github.io/Build-Instructions). 7 | 8 | ## Documentation 9 | 10 | See our [AnyDSL/Impala Website](https://anydsl.github.io/Impala). 11 | -------------------------------------------------------------------------------- /cmake/impala-config.cmake.in: -------------------------------------------------------------------------------- 1 | # Try to find all libraries and tools related to impala 2 | # in order to compile and link against .impala files 3 | # 4 | # Impala_BIN 5 | # Impala_INCLUDE_DIR 6 | # Impala_LIBRARY 7 | # Impala_FOUND 8 | 9 | cmake_minimum_required(VERSION 3.13.4) 10 | 11 | find_path(Impala_BUILD_DIR 12 | NAMES CMakeCache.txt 13 | PATHS ${Impala_BUILD_DIR} ${Impala_BUILD_DIR} "@CMAKE_CURRENT_BINARY_DIR@" 14 | ) 15 | find_path(Impala_INSTALL_DIR 16 | NAMES share/anydsl/cmake/impala-config.cmake 17 | PATHS "@CMAKE_INSTALL_PREFIX@" 18 | ) 19 | find_path(Impala_DIR 20 | NAMES impala-config.cmake 21 | PATHS ${Impala_DIR} $ENV{Impala_DIR} ${CMAKE_CURRENT_LIST_DIR} ${Impala_BUILD_DIR} ${Impala_INSTALL_DIR} ${Impala_SOURCE_DIR} "@CMAKE_CURRENT_BINARY_DIR@/share/anydsl/cmake" 22 | PATH_SUFFIXES share/anydsl/cmake 23 | ) 24 | find_path(Thorin_DIR 25 | NAMES thorin-config.cmake 26 | PATHS ${Thorin_DIR} $ENV{Thorin_DIR} ${CMAKE_CURRENT_LIST_DIR} "@CMAKE_CURRENT_BINARY_DIR@/share/anydsl/cmake" @Thorin_DIR@ 27 | PATH_SUFFIXES share/anydsl/cmake 28 | ) 29 | find_path(LLVM_DIR LLVMConfig.cmake PATHS ${LLVM_DIR} $ENV{LLVM_DIR} "@LLVM_DIR@") 30 | 31 | find_path(Impala_ROOT_DIR 32 | NAMES cmake/impala-config.cmake.in src/impala/impala.h 33 | PATHS ${Impala_DIR} $ENV{Impala_DIR} ${Impala_ROOT_DIR} "@CMAKE_CURRENT_SOURCE_DIR@" "@Impala_ROOT_DIR@" "@CMAKE_SOURCE_DIR@") 34 | 35 | if(NOT TARGET impala) 36 | include(${Impala_DIR}/impala-exports.cmake) 37 | endif() 38 | if(TARGET impala AND NOT Impala_BIN) 39 | set(Impala_BIN impala) 40 | else() 41 | find_program(Impala_BIN 42 | NAMES impala 43 | PATHS ${Impala_DIR}/../../../bin ${Impala_BUILD_DIR}/bin ${Impala_INSTALL_DIR}/bin "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@" 44 | PATH_SUFFIXES @CMAKE_CONFIGURATION_TYPES@) 45 | endif() 46 | 47 | if(TARGET libimpala) 48 | find_path(Impala_INCLUDE_DIR NAMES impala/impala.h PATHS ${Impala_ROOT_DIR}/src) 49 | set(Impala_LIBRARY libimpala) 50 | find_package(Thorin REQUIRED) 51 | endif() 52 | 53 | include(FindPackageHandleStandardArgs) 54 | find_package_handle_standard_args(Impala DEFAULT_MSG Impala_DIR) 55 | 56 | mark_as_advanced(Impala_ROOT_DIR Impala_BUILD_DIR Impala_INSTALL_DIR) 57 | -------------------------------------------------------------------------------- /doxyfile: -------------------------------------------------------------------------------- 1 | @INCLUDE = ../layout/doxyfile.skeleton 2 | 3 | PROJECT_NAME = Impala 4 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(impala) 2 | if(Thorin_HAS_LLVM_SUPPORT) 3 | add_subdirectory(intrinsicgen) 4 | endif() 5 | 6 | if(MSVC) 7 | target_compile_definitions(impala PRIVATE -D_SCL_SECURE_NO_WARNINGS) 8 | target_compile_definitions(impala PRIVATE -D_CRT_SECURE_NO_WARNINGS) 9 | target_compile_options(impala PRIVATE "/wd4800" "/wd4520") 10 | target_compile_options(impala PRIVATE "/experimental:external" "/external:anglebrackets" "/external:W0") 11 | else() 12 | target_compile_options(impala PRIVATE "-Wall" "-Wextra") 13 | endif() 14 | -------------------------------------------------------------------------------- /src/impala/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(IMPALA_SOURCES 2 | args.h 3 | ast.cpp 4 | ast.h 5 | ast_stream.cpp 6 | cgen.cpp 7 | cgen.h 8 | emit.cpp 9 | impala.cpp 10 | impala.h 11 | lexer.cpp 12 | lexer.h 13 | parser.cpp 14 | sema/infersema.cpp 15 | sema/namesema.cpp 16 | sema/type.cpp 17 | sema/type.h 18 | sema/typesema.cpp 19 | token.cpp 20 | token.h 21 | tokenlist.h 22 | ) 23 | 24 | add_library(libimpala ${IMPALA_SOURCES}) 25 | target_link_libraries(libimpala PRIVATE ${Thorin_LIBRARIES}) 26 | target_include_directories(libimpala PUBLIC ${Thorin_INCLUDE_DIRS} ${Impala_ROOT_DIR}/src) 27 | set_target_properties(libimpala PROPERTIES PREFIX "") 28 | 29 | add_executable(impala main.cpp) 30 | target_link_libraries(impala PRIVATE ${Thorin_LIBRARIES} libimpala) 31 | target_include_directories(impala PRIVATE ${Thorin_INCLUDE_DIRS} ${Impala_ROOT_DIR}/src) 32 | if(Thorin_HAS_LLVM_SUPPORT) 33 | set(Impala_LLVM_COMPONENTS core support) 34 | target_include_directories(impala SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS}) 35 | target_compile_definitions(impala PRIVATE ${LLVM_DEFINITIONS} -DLLVM_SUPPORT) 36 | llvm_config(impala ${AnyDSL_LLVM_LINK_SHARED} ${Impala_LLVM_COMPONENTS}) 37 | endif() 38 | if(MSVC) 39 | set_target_properties(impala PROPERTIES LINK_FLAGS /STACK:8388608) 40 | endif(MSVC) 41 | -------------------------------------------------------------------------------- /src/impala/cgen.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPALA_CGEN_H 2 | #define IMPALA_CGEN_H 3 | 4 | #include 5 | 6 | namespace impala { 7 | 8 | struct CGenOptions { 9 | CGenOptions() 10 | : structs_only(false) 11 | , fns_only(false) 12 | , file_name("interface.h") 13 | , guard("INTERFACE_H") 14 | {} 15 | 16 | bool structs_only : 1; 17 | bool fns_only : 1; 18 | std::string file_name; 19 | std::string guard; 20 | }; 21 | 22 | /** 23 | * Generates a C interface from the contents of an Impala module. 24 | * The typechecking pass has to be run before a call to this function. 25 | * 26 | * @param mod The module contents. 27 | * @param opts C interface generation options. 28 | * @param o The stream to use as output. 29 | * @return true on success, otherwise false 30 | */ 31 | bool generate_c_interface(const Module* mod, const CGenOptions& opts = CGenOptions(), std::ostream& o = std::cout); 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/impala/impala.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "impala/impala.h" 4 | 5 | #include "thorin/util/symbol.h" 6 | 7 | #include "impala/ast.h" 8 | #include "impala/token.h" 9 | 10 | namespace impala { 11 | 12 | int global_num_warnings = 0; 13 | int global_num_errors = 0; 14 | bool fancy_output = false; 15 | 16 | bool& fancy() { return fancy_output; } 17 | int& num_warnings() { return global_num_warnings; } 18 | int& num_errors() { return global_num_errors; } 19 | 20 | void init() { 21 | PrecTable::init(); 22 | Token::init(); 23 | } 24 | 25 | void check(std::unique_ptr& typetable, const Module* mod) { 26 | name_analysis(mod); 27 | type_inference(typetable, mod); 28 | type_analysis(mod); 29 | //borrow_check(mod); 30 | } 31 | 32 | Prec PrecTable::infix[Token::Num]; 33 | 34 | void PrecTable::init() { 35 | #define IMPALA_INFIX( tok, t_str, prec) PrecTable::infix[Token::tok] = Prec::prec; 36 | #define IMPALA_INFIX_ASGN(tok, t_str) PrecTable::infix[Token::tok] = Prec::Assign; 37 | #include "impala/tokenlist.h" 38 | } 39 | 40 | } 41 | 42 | /// Entry-point for the JIT in the runtime system. 43 | bool compile( 44 | const std::vector& file_names, 45 | const std::vector& file_data, 46 | thorin::World& world, 47 | std::ostream&) 48 | { 49 | static bool initialized = false; 50 | if (!initialized) { 51 | impala::init(); 52 | initialized = true; 53 | } 54 | impala::num_warnings() = 0; 55 | impala::num_errors() = 0; 56 | 57 | impala::Items items; 58 | for (size_t n = file_names.size(), i = 0; i < n; ++i) { 59 | auto file_name = file_names[i]; 60 | auto file_src = file_data[i]; 61 | std::istringstream program_is(file_src); 62 | impala::parse(items, program_is, file_name.c_str()); 63 | } 64 | 65 | auto module = std::make_unique(file_names.back().c_str(), std::move(items)); 66 | 67 | std::unique_ptr typetable; 68 | impala::check(typetable, module.get()); 69 | bool result = impala::num_errors() == 0; 70 | if (result) 71 | impala::emit(world, module.get()); 72 | 73 | return result; 74 | } 75 | -------------------------------------------------------------------------------- /src/impala/impala.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPALA_IMPALA_H 2 | #define IMPALA_IMPALA_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "thorin/world.h" 10 | #include "thorin/util/stream.h" 11 | 12 | #include "impala/token.h" 13 | #include "impala/sema/type.h" 14 | 15 | namespace impala { 16 | 17 | class ASTNode; 18 | class Item; 19 | class Module; 20 | typedef std::vector> Items; 21 | 22 | void init(); 23 | void parse(Items&, std::istream&, const char*); 24 | void name_analysis(const Module*); 25 | void type_inference(std::unique_ptr& typetable, const Module*); 26 | void type_analysis(const Module*); 27 | //void borrow_check(const ModContents*); 28 | void check(std::unique_ptr& typetable, const Module*); 29 | void emit(thorin::World&, const Module*); 30 | 31 | enum class Prec { 32 | Bottom, 33 | Assign = Bottom, 34 | Hlt, 35 | OrOr, AndAnd, 36 | Rel, 37 | Or, Xor, And, 38 | Shift, Add, Mul, 39 | As, 40 | Unary, 41 | RunRun, 42 | }; 43 | 44 | struct PrecTable { 45 | static Prec infix[Token::Num]; 46 | static Prec infix_l(int tag) { return infix[tag]; } 47 | static Prec infix_r(int tag) { return Prec(int(infix[tag])+1); } 48 | 49 | private: 50 | static void init(); 51 | friend void impala::init(); 52 | }; 53 | 54 | int& num_warnings(); 55 | int& num_errors(); 56 | bool& fancy(); 57 | 58 | template 59 | void warning(const Loc& loc, const char* fmt, Args... args) { 60 | ++num_warnings(); 61 | Stream s(std::cerr); 62 | s.fmt("{}: warning: ", loc).fmt(fmt, std::forward(args)...).endl(); 63 | } 64 | 65 | template 66 | void error(const Loc& loc, const char* fmt, Args... args) { 67 | ++num_errors(); 68 | Stream s(std::cerr); 69 | s.fmt("{}: error: ", loc).fmt(fmt, std::forward(args)...).endl(); 70 | } 71 | 72 | template 73 | struct Push { 74 | Push(T& t, T new_val) 75 | : old_(t) 76 | , ref_(t) 77 | { 78 | t = new_val; 79 | } 80 | ~Push() { ref_ = old_; } 81 | 82 | private: 83 | T old_; 84 | T& ref_; 85 | }; 86 | 87 | template 88 | inline Push push(T& t, U new_val) { return Push(t, new_val); } 89 | 90 | #define THORIN_LNAME__(name, line) name##__##line 91 | #define THORIN_LNAME_(name, line) THORIN_LNAME__(name, line) 92 | #define THORIN_LNAME(name) THORIN_LNAME_(name, __LINE__) 93 | 94 | #define THORIN_PUSH(what, with) auto THORIN_LNAME(thorin_push) = push((what), (with)) 95 | 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/impala/lexer.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPALA_LEXER_H 2 | #define IMPALA_LEXER_H 3 | 4 | #include 5 | 6 | #include "thorin/debug.h" 7 | 8 | #include "impala/token.h" 9 | 10 | namespace impala { 11 | 12 | class Lexer { 13 | public: 14 | Lexer(std::istream& stream, const char* filename); 15 | 16 | Token lex(); ///< Get next \p Token in stream. 17 | 18 | private: 19 | bool lex_identifier(std::string&); 20 | Token lex_suffix(std::string&, bool floating); 21 | Token literal_error(std::string&, bool floating); 22 | int next(); 23 | int peek() const { return stream_.peek(); } 24 | Loc curr() const { return loc_.anew_finis(); } 25 | 26 | template 27 | bool accept(std::string& str, Pred pred) { 28 | if (pred(peek())) { 29 | str += next(); 30 | return true; 31 | } 32 | return false; 33 | } 34 | 35 | template 36 | bool accept(Pred pred) { 37 | if (pred(peek())) { 38 | next(); 39 | return true; 40 | } 41 | return false; 42 | } 43 | 44 | bool accept(int expect) { return accept([&] (int got) { return got == expect; }); } 45 | bool accept(std::string& str, int expect) { return accept(str, [&] (int got) { return got == expect; }); } 46 | bool accept(char c) { return accept((int) c); } 47 | bool accept(std::string& str, char c) { return accept(str, (int) c); } 48 | 49 | std::istream& stream_; 50 | Loc loc_; 51 | Pos peek_; 52 | }; 53 | 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/intrinsicgen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(intrinsicgen main.cpp) 2 | target_link_libraries(intrinsicgen PRIVATE ${Thorin_LIBRARIES} libimpala) 3 | target_include_directories(intrinsicgen PRIVATE ${Thorin_INCLUDE_DIRS} ${Impala_ROOT_DIR}/src) 4 | llvm_config(intrinsicgen ${AnyDSL_LLVM_LINK_SHARED} core support) 5 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Python3 COMPONENTS Interpreter REQUIRED) 2 | 3 | find_package(LLVM QUIET CONFIG PATHS ${LLVM_DIR} $ENV{LLVM_DIR}) 4 | find_package(Clang QUIET CONFIG PATHS ${Clang_DIR} ${LLVM_DIR} PATH_SUFFIXES ../clang ../lib/cmake/clang) 5 | if(TARGET clang AND NOT Clang_BIN) 6 | get_target_property(Clang_BIN clang LOCATION) 7 | set(Clang_BIN ${Clang_BIN} CACHE FILEPATH "path to clang executable") 8 | endif() 9 | find_program(Clang_BIN clang 10 | PATHS ${LLVM_TOOLS_BINARY_DIR} ${LLVM_INSTALL_PREFIX}/bin 11 | PATH_SUFFIXES Release ${CMAKE_CONFIGURATION_TYPES} 12 | ) 13 | 14 | # add_library(rtmock STATIC rtmock.cpp) 15 | 16 | set(TEST_SCRIPT perform.py) 17 | set(TEST_ARGS --impala $ --clang ${Clang_BIN} --temp ${CMAKE_CURRENT_BINARY_DIR} --rtmock "${CMAKE_CURRENT_SOURCE_DIR}/rtmock.cpp") 18 | 19 | file(GLOB_RECURSE _testcases RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.impala") 20 | 21 | foreach(_test ${_testcases}) 22 | add_test(NAME ${_test} COMMAND ${Python3_EXECUTABLE} ${TEST_SCRIPT} ${TEST_ARGS} ${_test} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 23 | set_tests_properties(${_test} PROPERTIES SKIP_RETURN_CODE 77) 24 | endforeach() 25 | 26 | set(_content 27 | "CONFIGURATION = \"$\"\nIMPALA_BIN = \"$\"\nCLANG_BIN = \"${Clang_BIN}\"\nLIBRTMOCK = \"${CMAKE_CURRENT_SOURCE_DIR}/rtmock.cpp\"\nTEMP_DIR = \"${CMAKE_CURRENT_BINARY_DIR}\"\n") 28 | file(GENERATE OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/config$.py CONTENT ${_content}) 29 | -------------------------------------------------------------------------------- /test/blocked_loop2.impala: -------------------------------------------------------------------------------- 1 | fn blocked_loop(length: int, get_block_size: fn(int) -> int, bodyfn: fn(int, fn(int))) -> int { 2 | fn blocked_iter(cur_level: int, i: int, N: int, ret: fn(int)) { 3 | let block_size = get_block_size(cur_level); 4 | if block_size <= 0 { 5 | bodyfn(i) 6 | } 7 | let mut res = 0; 8 | 9 | fn rec(ii: int) { 10 | res += blocked_iter(cur_level + 1, ii, block_size); 11 | if (ii < N) { 12 | $rec(ii + block_size) 13 | } else { 14 | ret(res) 15 | } 16 | } 17 | $rec(i); 18 | } 19 | 20 | blocked_iter(0, 0, length); 21 | } 22 | 23 | fn main(i: int) -> int { 24 | fn get_block_size(i : int) -> int { 25 | if i == 0 { 4096 } 26 | else if i == 1 { 2048 } 27 | else if i == 2 { 1024 } 28 | else if i == 3 { 256 } 29 | else { 0 } 30 | } 31 | 32 | @blocked_loop(8192, get_block_size, |i: int| -> int i+7) 33 | } 34 | -------------------------------------------------------------------------------- /test/codegen/ackermann.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn a(m: int, n: int) -> int { 4 | if m == 0 { 5 | n + 1 6 | } else if n == 0 { 7 | a(m-1, 1) 8 | } else { 9 | a(m-1, a(m, n-1)) 10 | } 11 | } 12 | 13 | fn main() -> int { 14 | if a(3, 4) == 125 { 0 } else { 1 } 15 | } 16 | -------------------------------------------------------------------------------- /test/codegen/aliasing.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(p: &mut int, q: &mut int) -> int { 4 | let x = *p; 5 | *p = 1; 6 | *q = 2; 7 | x 8 | } 9 | 10 | fn main() -> int { 11 | let mut i = 23; 12 | if foo(&mut i, &mut i) == 23 { 0 } else { 1 } 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/alloc_definite_array.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | struct S { 4 | roots: &[u32], 5 | arr: &[i32], 6 | } 7 | 8 | fn main() -> int { 9 | let mut s : S; 10 | s.roots = ~[0u]; 11 | 12 | if true { 0 } else { 1 } 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/allset_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | // see https://github.com/AnyDSL/thorin/pull/97#issuecomment-442962062 4 | 5 | fn main() -> int { 6 | if !true { 1 } else { 0 } 7 | } 8 | -------------------------------------------------------------------------------- /test/codegen/and.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(a: bool, b: bool) -> bool { 4 | a && b 5 | } 6 | 7 | fn main() -> int { 8 | let mut res = 0; 9 | if foo(false, false) { 10 | res += 1; 11 | } 12 | if foo(false, true) { 13 | res += 2; 14 | } 15 | if foo( true, false) { 16 | res += 4; 17 | } 18 | if foo( true, true) { 19 | res += 8; 20 | } 21 | if res == 8 { 0 } else { 1 } 22 | } 23 | -------------------------------------------------------------------------------- /test/codegen/anonymous.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(_: int, _: int) -> int { 4 | let _ = 23; 5 | let _ = 42; 6 | 1337 7 | } 8 | 9 | fn main() -> int { 10 | if foo(1, 2) == 1337 { 0 } else { 1 } 11 | } 12 | -------------------------------------------------------------------------------- /test/codegen/array.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn test(array: &[i32]) -> i32 { 4 | array(0) 5 | } 6 | 7 | fn foo(mut a: [f32 * 4]) -> () { 8 | a(0) = 42.f; 9 | } 10 | 11 | fn bar(p: &mut i32) -> () { 12 | } 13 | 14 | fn main() -> int { 15 | let mut a = [0, 1, 2, 3]; 16 | bar(&mut a(4)); 17 | if test(a) == 0 { 0 } else { 1 } 18 | } 19 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/aobench.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/codegen/benchmarks/aobench.out -------------------------------------------------------------------------------- /test/codegen/benchmarks/fannkuch.impala: -------------------------------------------------------------------------------- 1 | // codegen "10" 2 | 3 | type char = u8; 4 | type str = [char]; 5 | 6 | extern "C" { 7 | fn anydsl_atoi(&str) -> int; 8 | fn print_int(int) -> (); 9 | } 10 | 11 | static mut s = [0, .. 16]; 12 | static mut t = [0, .. 16]; 13 | 14 | static mut max_n = 12; 15 | static mut maxflips = 0; 16 | static mut odd = 0; 17 | static mut checksum = 0; 18 | 19 | fn take_address(a: &[int * 16]) -> () {} 20 | 21 | fn range(a: int, b: int, body: fn(int) -> ()) -> () { 22 | if a < b { 23 | body(a); 24 | range(a+1, b, body) 25 | } 26 | } 27 | 28 | fn flip() -> int { 29 | for i in range(0, max_n) { 30 | t(i) = s(i) 31 | } 32 | 33 | let mut i = 1; 34 | while true { 35 | let mut x = 0; 36 | let mut y = t(0); 37 | while x < y { 38 | let c = t(x); 39 | t(x++) = t(y); 40 | t(y--) = c; 41 | } 42 | 43 | ++i; 44 | if t(t(0)) == 0 { 45 | break() 46 | } 47 | } 48 | i 49 | } 50 | 51 | fn rotate(n: int) -> () { 52 | let c = s(0); 53 | for i in range(1, n+1) { 54 | s(i-1) = s(i); 55 | } 56 | s(n) = c; 57 | } 58 | 59 | /* Tompkin-Paige iterative perm generation */ 60 | fn tk(n: int) -> () { 61 | let mut c = [0, .. 16]; 62 | take_address(&c); // HACK to prevent SSA contruction of c 63 | let mut i = 0; 64 | while i < n { 65 | rotate(i); 66 | if c(i) >= i { 67 | c(i++) = 0; 68 | continue() 69 | } 70 | 71 | ++c(i); 72 | i = 1; 73 | odd = !odd; 74 | if s(0) != 0 { 75 | let f = 76 | if s(s(0)) != 0 { 77 | flip() 78 | } else { 79 | 1 80 | }; 81 | if f > maxflips { 82 | maxflips = f; 83 | } 84 | checksum += if odd != 0 { -f } else { f } 85 | } 86 | } 87 | } 88 | 89 | fn main(argc: int, argv: &[&str]) -> int { 90 | let n = if argc >= 2 { anydsl_atoi(argv(1)) } else { 0 }; 91 | max_n = n; 92 | for i in range(0, max_n) { 93 | s(i) = i; 94 | } 95 | tk(max_n); 96 | print_int(checksum); 97 | print_int(max_n); 98 | print_int(maxflips); 99 | 0 100 | } 101 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/fannkuch.out: -------------------------------------------------------------------------------- 1 | 73196 2 | 10 3 | 38 4 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/mandelbrot.impala: -------------------------------------------------------------------------------- 1 | // codegen "3000" 2 | 3 | type char = i8; 4 | type str = [char]; 5 | 6 | extern "C" { 7 | fn anydsl_atoi(&str) -> int; 8 | fn print_header(int, int) -> (); 9 | fn put_u8(u8) -> (); 10 | } 11 | 12 | fn range(a: f64, b: f64, body: fn(f64) -> ()) -> () { 13 | if a < b { 14 | body(a); 15 | range(a+1.0, b, body) 16 | } 17 | } 18 | 19 | fn main(argc: int, argv: &[&str]) -> int { 20 | let n = if argc >= 2 { anydsl_atoi(argv(1)) } else { 0 }; 21 | let w = n as f64; 22 | let h = n as f64; 23 | let iter = 50; 24 | let limit = 2.0; 25 | 26 | print_header(w as int, h as int); 27 | 28 | let mut bit_num = 0; 29 | let mut byte_acc = 0_u8; 30 | 31 | for y in range(0.0, h) { 32 | for x in range(0.0, w) { 33 | let mut Zr = 0.0; 34 | let mut Zi = 0.0; 35 | let mut Tr = 0.0; 36 | let mut Ti = 0.0; 37 | let Cr = (2.0*x)/w - 1.5; 38 | let Ci = (2.0*y)/h - 1.0; 39 | 40 | let mut i = 0; 41 | while i < iter && (Tr+Ti <= limit*limit) { 42 | Zi = 2.0*Zr*Zi + Ci; 43 | Zr = Tr - Ti + Cr; 44 | Tr = Zr * Zr; 45 | Ti = Zi * Zi; 46 | ++i; 47 | } 48 | 49 | byte_acc <<= 1u8; 50 | if Tr+Ti <= limit*limit { 51 | byte_acc |= 0x01_u8; 52 | } 53 | 54 | ++bit_num; 55 | 56 | if bit_num == 8 { 57 | put_u8(byte_acc); 58 | byte_acc = 0_u8; 59 | bit_num = 0; 60 | } else if x == w-1.0 { 61 | put_u8(byte_acc << (8_u8 - (w as u8) % 8_u8)); 62 | byte_acc = 0_u8; 63 | bit_num = 0; 64 | } 65 | } 66 | } 67 | 0 68 | } 69 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/mandelbrot.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/codegen/benchmarks/mandelbrot.out -------------------------------------------------------------------------------- /test/codegen/benchmarks/meteor.out: -------------------------------------------------------------------------------- 1 | 2098 solutions found 2 | 3 | 0 0 0 0 1 4 | 2 2 2 0 1 5 | 2 6 6 1 1 6 | 2 6 1 5 5 7 | 8 6 5 5 5 8 | 8 6 3 3 3 9 | 4 8 8 9 3 10 | 4 4 8 9 3 11 | 4 7 4 7 9 12 | 7 7 7 9 9 13 | 14 | 9 9 9 9 8 15 | 9 6 6 8 5 16 | 6 6 8 8 5 17 | 6 8 2 5 5 18 | 7 7 7 2 5 19 | 7 4 7 2 0 20 | 1 4 2 2 0 21 | 1 4 4 0 3 22 | 1 4 0 0 3 23 | 1 1 3 3 3 24 | 25 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/nbody.out: -------------------------------------------------------------------------------- 1 | -0.169075164 2 | -0.169059681 3 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/pidigits.impala: -------------------------------------------------------------------------------- 1 | // codegen -lgmp -lm "10000" 2 | 3 | type char = u8; 4 | type str = [char]; 5 | 6 | struct mpz_t { 7 | a: i32, 8 | b: i32, 9 | c: &i64, 10 | } 11 | 12 | extern "C" { 13 | fn "__gmpz_add" mpz_add(&mpz_t, &mpz_t, &mpz_t) -> (); 14 | fn "__gmpz_addmul_ui" mpz_addmul_ui(&mpz_t, &mpz_t, u64) -> (); 15 | fn "__gmpz_submul_ui" mpz_submul_ui(&mpz_t, &mpz_t, u64) -> (); 16 | fn "__gmpz_cmp" mpz_cmp(&mpz_t, &mpz_t) -> int; 17 | fn "__gmpz_get_ui" mpz_get_ui(&mpz_t) -> u64; 18 | fn "__gmpz_mul_ui" mpz_mul_ui(&mpz_t, &mpz_t, u64) -> (); 19 | fn "__gmpz_set_ui" mpz_set_ui(&mpz_t, u64) -> (); 20 | fn "__gmpz_tdiv_q" mpz_tdiv_q(&mpz_t, &mpz_t, &mpz_t) -> (); 21 | fn "__gmpz_init" mpz_init(&mpz_t) -> (); 22 | fn "__gmpz_init_set_ui" mpz_init_set_ui(&mpz_t, u64) -> (); 23 | fn anydsl_atoi(&str) -> int; 24 | fn print_digits(u64) -> (); 25 | fn putchar(int) -> int; 26 | fn print_int(int) -> (); 27 | fn print_char(u8) -> (); 28 | } 29 | 30 | static mut tmp1: mpz_t; 31 | static mut tmp2: mpz_t; 32 | static mut acc: mpz_t; 33 | static mut den: mpz_t; 34 | static mut num: mpz_t; 35 | 36 | fn extract_digit(nth: u64 ) -> u64 { 37 | // joggling between tmp1 and tmp2, so GMP won't have to use temp buffers 38 | mpz_mul_ui(&tmp1, &num, nth); 39 | mpz_add(&tmp2, &tmp1, &acc); 40 | mpz_tdiv_q(&tmp1, &tmp2, &den); 41 | mpz_get_ui(&tmp1) 42 | } 43 | 44 | fn eliminate_digit(d: u64) -> () { 45 | mpz_submul_ui(&acc, &den, d); 46 | mpz_mul_ui(&acc, &acc, 10_u64); 47 | mpz_mul_ui(&num, &num, 10_u64); 48 | } 49 | 50 | fn next_term(k: u64) -> () { 51 | let k2 = k * 2_u64 + 1_u64; 52 | 53 | mpz_addmul_ui(&acc, &num, 2_u64); 54 | mpz_mul_ui(&acc, &acc, k2); 55 | mpz_mul_ui(&den, &den, k2); 56 | mpz_mul_ui(&num, &num, k); 57 | } 58 | 59 | fn main(argc: int, argv: &[&str]) -> int { 60 | let n = if argc >= 2 { anydsl_atoi(argv(1)) } else { 0 }; 61 | mpz_init(&tmp1); 62 | mpz_init(&tmp2); 63 | 64 | mpz_init_set_ui(&acc, 0_u64); 65 | mpz_init_set_ui(&den, 1_u64); 66 | mpz_init_set_ui(&num, 1_u64); 67 | 68 | let mut k = 0_u64; 69 | let mut i = 0_u64; 70 | while i < (n as u64) { 71 | next_term(++k); 72 | if mpz_cmp(&num, &acc) > 0 { 73 | continue() 74 | } 75 | 76 | let d = extract_digit(3_u64); 77 | if d != extract_digit(4_u64) { 78 | continue() 79 | } 80 | 81 | putchar('0' as int + d as int); 82 | if ++i % 10_u64 == 0_u64 { 83 | print_digits(i); 84 | } 85 | eliminate_digit(d); 86 | } 87 | 0 88 | } 89 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/regex.out: -------------------------------------------------------------------------------- 1 | agggtaaa|tttaccct 18 2 | [cgt]gggtaaa|tttaccc[acg] 63 3 | a[act]ggtaaa|tttacc[agt]t 211 4 | ag[act]gtaaa|tttac[agt]ct 145 5 | agg[act]taaa|ttta[agt]cct 273 6 | aggg[acg]aaa|ttt[cgt]ccct 77 7 | agggt[cgt]aa|tt[acg]accct 72 8 | agggta[cgt]a|t[acg]taccct 79 9 | agggtaa[cgt]|[acg]ttaccct 110 10 | 11 | 2541745 12 | 2500000 13 | 3339270 14 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/spectral.impala: -------------------------------------------------------------------------------- 1 | // codegen -lm "1800" 2 | 3 | type char = i8; 4 | type str = [char]; 5 | 6 | extern "C" { 7 | fn anydsl_atoi(&str) -> int; 8 | fn sqrt(f64) -> f64; 9 | fn print_f64(f64) -> (); 10 | } 11 | 12 | fn range(a: int, b: int, body: fn(int) -> ()) -> () { 13 | if a < b { 14 | body(a); 15 | range(a+1, b, body) 16 | } 17 | } 18 | 19 | fn eval_A(i: int, j: int) -> f64 { 20 | 1.0/(((i+j)*(i+j+1)/2+i+1) as f64) 21 | } 22 | 23 | fn eval_A_times_u(N: int, u: &[f64], Au: &mut [f64]) -> () { 24 | for i in range(0, N) { 25 | Au(i) = 0.0; 26 | for j in range(0, N) { 27 | Au(i) += eval_A(i, j) * u(j); 28 | } 29 | } 30 | } 31 | 32 | fn eval_At_times_u(N: int, u: &[f64], Au: &mut [f64]) -> () { 33 | for i in range(0, N) { 34 | Au(i) = 0.0; 35 | for j in range(0, N) { 36 | Au(i) += eval_A(j, i) * u(j); 37 | } 38 | } 39 | } 40 | 41 | fn eval_AtA_times_u(N: int, u: &[f64], AtAu: &mut [f64]) -> () { 42 | let v = ~[N: f64]; 43 | eval_A_times_u(N, u, v); 44 | eval_At_times_u(N, v, AtAu); 45 | } 46 | 47 | fn main(argc: int, argv: &[&str]) -> int { 48 | let n = if argc >= 2 { anydsl_atoi(argv(1)) } else { 0 }; 49 | let mut u = ~[n: f64]; 50 | let v = ~[n: f64]; 51 | 52 | for i in range(0, n) { 53 | u(i) = 1.0; 54 | } 55 | 56 | for i in range(0, 10) { 57 | eval_AtA_times_u(n, u, v); 58 | eval_AtA_times_u(n, v, u); 59 | } 60 | 61 | let mut vBv = 0.0; 62 | let mut vv = 0.0; 63 | 64 | for i in range(0, n) { 65 | vBv += u(i)*v(i); 66 | vv += v(i)*v(i); 67 | } 68 | 69 | print_f64(sqrt(vBv/vv)); 70 | 0 71 | } 72 | -------------------------------------------------------------------------------- /test/codegen/benchmarks/spectral.out: -------------------------------------------------------------------------------- 1 | 1.274224152 2 | -------------------------------------------------------------------------------- /test/codegen/bind_ret_inner_fn.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn f(b: bool, i: int) -> int { 4 | fn F() -> ! { r(i-1) } 5 | fn T() -> ! { r(i) } 6 | let ret : fn(int) -> ! = return; 7 | fn r(x: int) -> ! { ret(x) } 8 | if (b) { 9 | T() 10 | } else { 11 | F() 12 | } 13 | } 14 | 15 | fn main() -> int { 16 | f(true, 5) 17 | } 18 | -------------------------------------------------------------------------------- /test/codegen/bitcast.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "thorin" { 4 | fn bitcast[D, S](S) -> D; 5 | } 6 | 7 | fn main() -> int { 8 | bitcast(0.f) 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/bool_to_signed.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn f(b: bool) -> int { 4 | b as int 5 | } 6 | 7 | fn main() -> int { 8 | if (4*f(true) + f(false)) == 4 { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/bottom.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | // https://github.com/AnyDSL/thorin/issues/28 4 | struct Foo { 5 | x: int, 6 | y: float, 7 | } 8 | 9 | fn arr() -> [int * 2] { 10 | let mut bar: [int * 2]; 11 | bar(0) = 23; 12 | bar(1) = 42; 13 | bar 14 | } 15 | 16 | fn tuple() -> (int, float) { 17 | let mut bar: (int, float); 18 | bar(0) = 23; 19 | bar(1) = 42.f; 20 | bar 21 | } 22 | 23 | fn foo() -> Foo { 24 | let mut bar: Foo; 25 | bar.x = 23; 26 | bar.y = 42.f; 27 | bar 28 | } 29 | 30 | 31 | fn main() -> int { 32 | let a = arr(); 33 | let t = tuple(); 34 | let f = foo(); 35 | if a(0) as f32 + a(1) as f32 + t(0) as f32 + t(1) + f.x as f32 + f.y == 195.f { 0 } else { 1 } 36 | } 37 | -------------------------------------------------------------------------------- /test/codegen/break.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, z: int, body: fn(int)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1, z, body) 7 | } 8 | } 9 | 10 | fn main() -> int { 11 | let mut res: int = 0; 12 | for i in range(0, 15) { 13 | if i*i > 42 { 14 | break() 15 | } 16 | res += 1; 17 | } 18 | if res == 7 { 0 } else { 1 } 19 | } 20 | -------------------------------------------------------------------------------- /test/codegen/cast.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let a: &mut [i32] = ~[17:i32]; 5 | a(3) = 3.f as i32; 6 | if a(3) == 3 { 0 } else { 1 } 7 | } 8 | -------------------------------------------------------------------------------- /test/codegen/cfa_out.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn out(fA: fn(fn(fn(fn(int) -> !) -> !, fn(int) -> !) -> !) -> !, fB: fn(fn(fn(fn(int) -> !) -> !, fn(int) -> !) -> !) -> !) -> () { 4 | } 5 | 6 | fn main() -> int { 7 | let mut i = 42; 8 | fn M(c: int) -> ! { return(c) } 9 | fn N(c: int) -> ! { return(c) } 10 | fn C(pc: fn(int) -> !) -> ! { pc(i++) } 11 | fn A(pa: fn(fn(fn(int) -> !) -> !, fn(int) -> !) -> !) -> ! { pa(C, M) } 12 | fn B(pb: fn(fn(fn(int) -> !) -> !, fn(int) -> !) -> !) -> ! { pb(C, N) } 13 | 14 | out(A, B); 15 | 0 16 | } 17 | -------------------------------------------------------------------------------- /test/codegen/char.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let a = '\0'; 5 | let b = '\n'; 6 | let c = '\t'; 7 | let d = '\''; 8 | let e = '\\'; 9 | if a + b + c + d + e == 150_u8 { 0 } else { 1 } 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/complex_for.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn print_int(i32) -> (); 5 | } 6 | 7 | fn range(mut b: i32, e: i32, body: fn(i32) -> ()) -> () { 8 | while b < e { 9 | body(b++) 10 | } 11 | } 12 | 13 | fn sum_range(mut b: i32, e: i32, body: fn(i32) -> i32) -> i32 { 14 | let mut sum = 0; 15 | while b < e { 16 | sum += b; 17 | b += body(b) 18 | } 19 | sum 20 | } 21 | 22 | fn main() -> i32 { 23 | for i in range(0, 3) { 24 | print_int(i); // 0, 1, 2 25 | } 26 | 27 | let mut step = 1; 28 | let sum = for i in sum_range(0, 16) { 29 | if step == 3 { 30 | step++; 31 | continue(1) 32 | } 33 | print_int(i); 34 | step++ 35 | }; 36 | if sum == 29 { 0 } else { 1 } 37 | } 38 | -------------------------------------------------------------------------------- /test/codegen/conditionals.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn @scalar(f: f32) -> f32 { f } 4 | 5 | fn main() -> i32 { 6 | let mut value = 1.f; 7 | if 1.f < scalar(0.01f) || 0.2f < scalar(0.01f) || 0.3f < scalar(0.01f) { 8 | value = 0.7f; 9 | } 10 | if 1.f < scalar(0.01f) && 0.2f < scalar(0.01f) && 0.3f < scalar(0.01f) { 11 | value = 0.7f; 12 | } 13 | if value == 1.0f { 0 } else { 1 } 14 | } 15 | -------------------------------------------------------------------------------- /test/codegen/constant_ordering_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | enum E { 4 | A, 5 | B 6 | } 7 | 8 | extern fn f() -> [[E * 2] * 1] { [[E::A, E::A]] } 9 | 10 | fn main() -> int { 11 | 0 12 | } 13 | -------------------------------------------------------------------------------- /test/codegen/continue.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, z: int, body: fn(int)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1, z, body) 7 | } 8 | } 9 | 10 | fn main() -> int { 11 | let mut a: int = 0; 12 | for i in range(0, 100) { 13 | if (i % 2 == 0) { 14 | continue() 15 | } 16 | ++a; 17 | } 18 | if a == 50 { 0 } else { 1 } 19 | } 20 | -------------------------------------------------------------------------------- /test/codegen/conversion_trait.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | trait Conv[T] { 4 | fn conv(self: &Self) -> T; 5 | } 6 | 7 | trait Add { 8 | fn add(self: Self, x:Self) -> Self; 9 | } 10 | 11 | trait Eq { 12 | fn eq(self: &Self, o: &Self) -> bool; 13 | } 14 | 15 | ///////////////////////////////////////////////// 16 | 17 | struct S { x : int } 18 | 19 | impl Conv[int] for S { 20 | fn conv(self: &S) -> int { (*self).x } 21 | } 22 | 23 | impl Add for S { 24 | fn add(self: S, s: S) -> S { S { x:(self.x + s.x) } } 25 | } 26 | 27 | impl Eq for S { 28 | fn eq(self: &S, o : &S) -> bool { (*self).x == (*o).x } 29 | } 30 | 31 | ////////////////////////////////////////////////// 32 | 33 | impl Conv[S] for int { 34 | fn conv(self: &int) -> S { S { x : *self } } 35 | } 36 | 37 | impl Add for int { 38 | fn add(self: int, x: int) -> int { self + x } 39 | } 40 | 41 | impl Eq for int { 42 | fn eq(self: &int, o: &int) -> bool { *self == *o } 43 | } 44 | 45 | ////////////////////////////////////////////////// 46 | 47 | fn assertAddEqual[T:Eq+Add+Conv[U], U:Eq+Add+Conv[T]](t : T, u : U) -> bool { 48 | let a : T = t.add(u.conv()); 49 | let b : U = u.add(t.conv()); 50 | 51 | if ((a.conv() == b) && (b.conv() == a)) { 52 | true 53 | } else { 54 | false 55 | } 56 | } 57 | 58 | ////////////////////////////////////////////////// 59 | 60 | fn main() -> int { 61 | let s = S { x:5 }; 62 | let t = 5; 63 | 64 | if assertAddEqual(s, t) { 0 } else { 1 } 65 | } 66 | -------------------------------------------------------------------------------- /test/codegen/cur_bb_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut k = 0; 5 | if k == 0 { 6 | return(0) 7 | } 8 | k=1; 9 | if false { 0 } else { 1 } 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/diderot.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn range(a: int, b: int, body: fn(int)->()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a+1, b, body) 7 | } 8 | } 9 | 10 | fn range_xy[L](mut l: L, xn: int, yn: int, 11 | body: fn(L, int, int) -> L) -> L 12 | { 13 | for y in range(0, yn) { 14 | for x in range(0, xn) { 15 | l = body(l, x, y) 16 | } 17 | } 18 | 19 | l 20 | } 21 | 22 | 23 | fn initially[G,T,R](g: G, xn: int, yn: int, make_strand: fn(G) -> T, write_result: fn(int, int, G, R) -> G, update: fn(G, T, int, int, /*loop*/ fn(T) -> !, /*stabilize*/ fn(R) -> !, /*die*/ fn() -> !)) -> G { 24 | range_xy(g, xn, yn, |g, x, y, ret| { 25 | fn loop(strand: T) { 26 | update(g, strand, x, y, 27 | loop, 28 | stab, 29 | die) 30 | } 31 | 32 | fn stab(res: R) { ret(write_result(x, y, g, res)) } 33 | fn die() { ret(g) } 34 | 35 | loop(make_strand(g)) 36 | }) 37 | } 38 | 39 | fn main() -> int { 40 | fn update(g: i64, t: i16, xn: int, yn: int, loop: fn(i16) -> !, stabilize: fn(i16) -> !, die: fn() -> !) { 41 | if xn + yn < 42 { 42 | die() 43 | } 44 | if t == 23_i16 { 45 | stabilize(t) 46 | } 47 | 48 | loop(t + 1_i16) 49 | } 50 | 51 | fn make_strand(g: i64) -> i16 { 24_i16 } 52 | fn write_result(x: int, y: int, g: i64, r: i16) -> i64 { 25_i64 } 53 | 54 | let mut g = 26_i64; 55 | 56 | if initially(g, 100, 200, make_strand, write_result, update) == 0i64 { 0 } else { 1 } 57 | } 58 | -------------------------------------------------------------------------------- /test/codegen/empty_string.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn println(&[u8]) -> (); 5 | } 6 | 7 | fn main() -> int { 8 | println(""); 9 | if true { 0 } else { 1 } 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/empty_string.out: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/codegen/endless_mangling.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn f(a: int, ret1: fn(int) -> !, ret2: fn(int) -> !) -> ! { 4 | if a < 42 { 5 | f(a + 1, |i| -> ! ret2(a+i), |i| -> ! ret1(a-i)) 6 | } else { 7 | ret1(a+2) 8 | } 9 | } 10 | 11 | extern fn g(i: int) -> int { 12 | f(i, return, |i: int| -> ! return(i)) 13 | } 14 | 15 | fn main() -> int { 0 } 16 | -------------------------------------------------------------------------------- /test/codegen/endless_pe.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | struct Node { 4 | next: &Node 5 | } 6 | 7 | extern 8 | fn ext(p: &Node) -> i32 { 9 | if p != 0 as &Node { 10 | ext(p.next); 11 | } 12 | 0 13 | } 14 | 15 | fn main() -> i32 { 0 } 16 | -------------------------------------------------------------------------------- /test/codegen/fac_double.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: double, z: double, body: fn(double)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1.0, z, body) 7 | } 8 | } 9 | 10 | extern fn fac(n : double) -> double { 11 | if (n <= 1.0) { 12 | return(1.0) 13 | } 14 | 15 | let mut r : double = 1.0; 16 | for i in range(2.0, n+1.0) { 17 | r *= i; 18 | } 19 | 20 | r 21 | } 22 | 23 | fn main() -> int { 24 | if fac(4.0) == 24.0 { 0 } else { 1 } 25 | } 26 | -------------------------------------------------------------------------------- /test/codegen/fac_float.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: float, z: float, body: fn(float)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1.f, z, body) 7 | } 8 | } 9 | 10 | extern fn fac(n : float) -> float { 11 | if (n <= 1.f) { 12 | return(1.f) 13 | } 14 | 15 | let mut r : float = 1.f; 16 | for i in range(2.f, n+1.f) { 17 | r *= i; 18 | } 19 | 20 | r 21 | } 22 | 23 | fn main() -> int { 24 | if fac(4.0f) == 24.0f { 0 } else { 1 } 25 | } 26 | -------------------------------------------------------------------------------- /test/codegen/fac_int.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, z: int, body: fn(int)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1, z, body) 7 | } 8 | } 9 | 10 | fn fac(n : int) -> int { 11 | if n <= 1 { 12 | return(1) 13 | } 14 | 15 | let mut r = 1; 16 | for i in range(2, n + 1) { 17 | r *= i 18 | } 19 | 20 | r 21 | } 22 | 23 | fn main() -> int { 24 | if fac(5) == 120 { 0 } else { 1 } 25 | } 26 | -------------------------------------------------------------------------------- /test/codegen/fac_nest.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn fac(n: int) -> int { 4 | fn helper(r: int, i: int) -> int { 5 | if i <= n { 6 | helper(r*i, i+1) 7 | } else { 8 | r 9 | } 10 | } 11 | 12 | if n <= 1 { 13 | 1 14 | } else { 15 | helper(1, 2) 16 | } 17 | } 18 | 19 | fn main() -> int { 20 | if fac(4) == 24 { 0 } else { 1 } 21 | } 22 | -------------------------------------------------------------------------------- /test/codegen/fac_rec.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn fac_rec(n: int) -> int { 4 | if (n <= 0) { 5 | 1 6 | } else { 7 | n * fac_rec(n-1) 8 | } 9 | } 10 | 11 | fn main() -> int { 12 | if fac_rec(5) == 120 { 0 } else { 1 } 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/fac_tail.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn fac(n: int) -> int { 4 | if (n <= 1) { 5 | 1 6 | } else { 7 | helper(1, 2, n) 8 | } 9 | } 10 | 11 | fn helper(r: int, i: int, n: int) -> int { 12 | if (i <= n) { 13 | helper(r * i, i + 1, n) 14 | } else { 15 | r 16 | } 17 | } 18 | 19 | fn main() -> int { 20 | if fac(4) == 24 { 0 } else { 1 } 21 | } 22 | -------------------------------------------------------------------------------- /test/codegen/fib.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, z: int, body: fn(int)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1, z, body) 7 | } 8 | } 9 | 10 | fn fib(n: int, body: fn(int)->()) -> () { 11 | let ret = return; 12 | fn loop(n: int, cur: int, prev: int) -> ! { 13 | if (n != 0) { 14 | body(cur, || -> ! loop(n-1, cur + prev, cur) ) 15 | } else { 16 | ret() 17 | } 18 | } 19 | loop(n, 1, 0) 20 | } 21 | 22 | fn main() -> int { 23 | let mut result: int = 0; 24 | for i in range(0, 15000000) { 25 | fib(13, 26 | |f: int| result = result % 4 + f, 27 | continue 28 | ) 29 | } 30 | if result == 236 { 0 } else { 1 } 31 | } 32 | -------------------------------------------------------------------------------- /test/codegen/fieldexpr.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(rays: &Ray) -> f32 { 4 | rays.org.x 5 | } 6 | 7 | struct Ray { 8 | org: Vec4 9 | } 10 | 11 | struct Vec4 { 12 | x: f32 13 | } 14 | 15 | fn main() -> int { 16 | if foo(Ray{org: Vec4{x: 23.f}}) == 23.f { 0 } else { 1 } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/codegen/float_literal.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | fn main() -> int { 3 | if .5 == 0.5 { 0 } else { 1 } 4 | } 5 | -------------------------------------------------------------------------------- /test/codegen/fold.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn seq(a: int, b: int) -> (int, fn(int, fn(int) -> ()) -> ()) { 4 | fn stream(i: int, body: fn(int) -> ()) -> () { 5 | if (i <= b) { 6 | body(i, || -> ! { stream(i+1, body, return) }) 7 | } else { 8 | return() 9 | } 10 | } 11 | (a, stream) 12 | } 13 | 14 | fn fold(f: fn(int, int) -> int, z: int, stream: (int, fn(int, fn(int) -> ()) -> ())) -> int { 15 | let mut res = z; 16 | let a = stream(0); 17 | let s = stream(1); 18 | let ret = return; 19 | s(a, |i: int| -> () { 20 | res = f(res, i); 21 | return() 22 | }, || -> ! { ret(res) }) 23 | } 24 | 25 | fn main() -> int { 26 | if fold(|a: int, b: int| -> int { a + b }, 0, seq(0, 10)) == 55 { 0 } else { 1 } 27 | } 28 | -------------------------------------------------------------------------------- /test/codegen/generic_get.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn get[T]() -> T { 4 | let mut tuple: (T, T); 5 | tuple(0) 6 | } 7 | 8 | fn main() -> int { 9 | let mut x = get(); 10 | x = 0; 11 | x 12 | } 13 | -------------------------------------------------------------------------------- /test/codegen/generic_while.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn generic_while[L, B](l : L, 4 | head : fn(L) -> (B, bool), 5 | body : fn(B) -> L) -> B 6 | { 7 | head(l, 8 | |b : B, cond : bool| -> ! { 9 | if (cond) { 10 | generic_while(body(b), head, body) 11 | } else { 12 | return(b) 13 | } 14 | } 15 | ) 16 | } 17 | 18 | fn main() -> int { 19 | if generic_while(/*counter*/ 0, 20 | |i : int| -> (int, bool) { return(i, i < 42) }, 21 | |i : int| -> int { i + 1 }) == 42 { 22 | 0 23 | } else { 24 | 1 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/codegen/growing_stack.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn take_address(&int) -> () {} 4 | 5 | fn range(a: int, b: int, body: fn(int) -> ()) -> () { 6 | if a < b { 7 | body(a); 8 | range(a+1, b, body) 9 | } 10 | } 11 | 12 | fn main() -> int { 13 | let mut sum = 0; 14 | for i in range(0, 100000) { 15 | let mut foo = i; 16 | take_address(&foo); 17 | sum += foo 18 | } 19 | if sum == 704982704 { 0 } else { 1 } 20 | } 21 | -------------------------------------------------------------------------------- /test/codegen/hello_world.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn println(&[u8]) -> (); 5 | } 6 | 7 | fn main() -> int { 8 | println("hello world"); 9 | if true { 0 } else { 1 } 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/hello_world.out: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /test/codegen/if_return_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(i: int) -> int { 4 | if i == 23 { 5 | return(23) 6 | } else { 7 | return(42) 8 | } 9 | } 10 | 11 | fn main() -> int { 12 | if foo(23) == 23 { 0 } else { 1 } 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/if_stmt_expr.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let i = (if true {23} else {42}) + 1; 5 | if i == 24 {0} else {1} 6 | } 7 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_atomic_decrement.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut a = 1; 5 | let a_dec_zero = atomic_dec(&mut a); 6 | 7 | let mut b = 9; 8 | let b_dec_zero = atomic_dec(&mut b); 9 | 10 | if a_dec_zero && !b_dec_zero && a == 0 && b == 8 { 0 } else { 1 } 11 | } 12 | 13 | fn atomic_dec(p: &mut i32) -> bool { 14 | let mut res: bool = false; 15 | asm ("lock; decl $1; sete $0;" 16 | : /*"=r" (p),*/ "=q" (res) 17 | : "*m" (p) 18 | : "memory" 19 | : "volatile" 20 | ); 21 | res 22 | } 23 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_simple_1.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut a = 4; 5 | let b = 3; 6 | asm("addl $1, $0" : "=r"(a) : "r"(b), "0"(a)); 7 | 8 | if a == 7 { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_simple_2.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let a = 10; 5 | let mut b: i32; 6 | asm ("movl $1, %eax;" 7 | "movl %eax, $0;" 8 | "addl $$4, $0;" 9 | :"=r"(b) /* output */ 10 | :"r"(a) /* input */ 11 | :"{eax}" /* clobbered register */ 12 | ); 13 | 14 | if b == 14 { 0 } else { 1 } 15 | } 16 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_simple_3.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut a = 4; 5 | let mut b = 3; 6 | let c = 7; 7 | asm("addl $2, $0\n\t" 8 | "movl $1, %eax\n\t" 9 | "addl %eax, $0\n\t" 10 | "subl %eax, $1" 11 | : "=r"(a), "=r"(b) 12 | : "r"(c), "0"(a), "1"(b) 13 | : "{eax}" 14 | ); 15 | 16 | if a == 14 && b == 0 { 0 } else { 1 } 17 | } 18 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_strcpy.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn println(&[u8]) -> (); 5 | } 6 | 7 | fn main() -> int { 8 | let mut dst = "Don't overwrite me"; 9 | let src = "Come on, copy me!\n"; 10 | strcpy(&mut dst, src, 19u32); 11 | 12 | println(dst); 13 | 0 14 | } 15 | 16 | fn strcpy(mut dst: &[u8], mut src: &[u8], mut count: u32) -> () { 17 | asm("cld\n\t" 18 | "rep movsb" 19 | : "={si}"(src), "={di}"(dst), "={cx}"(count) 20 | : "0"(src), "1"(dst), "2"(count) 21 | : "memory" 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_strcpy.out: -------------------------------------------------------------------------------- 1 | Come on, copy me! 2 | 3 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_syscall.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let str = "I'm a string, get me out of here!\n"; 5 | let len = 34; 6 | 7 | // prints a string 8 | asm("syscall;" /* call kernel */ 9 | :: "{rax}"(1), "{rdi}"(1), "{rsi}"(&str), "{rdx}"(len) 10 | ); 11 | 12 | // exits with 0 13 | asm("syscall;" /* Enter kernel mode */ 14 | :: "{rax}"(60), "{rdi}"(0) 15 | ); 16 | 17 | 1 18 | } 19 | -------------------------------------------------------------------------------- /test/codegen/inline_asm/x86_64/asm_syscall.out: -------------------------------------------------------------------------------- 1 | I'm a string, get me out of here! 2 | -------------------------------------------------------------------------------- /test/codegen/labeled_break.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, z: int, body: fn(int)->()) -> () { 4 | if a < z { 5 | body(a); 6 | range(a+1, z, body) 7 | } 8 | } 9 | 10 | fn main() -> int { 11 | let mut r = 0; 12 | for i in range(0, 10) { 13 | let outer = break; 14 | 15 | for j in range(0, 10) { 16 | if (i == j) { 17 | outer() 18 | } 19 | r++; 20 | } 21 | } 22 | 23 | if r == 0 { 0 } else { 1 } 24 | } 25 | -------------------------------------------------------------------------------- /test/codegen/lambda_assert.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn iteration_sep_advanced() -> () { 4 | init_zero(~[23: f32]); 5 | } 6 | 7 | fn range(a: int, b: int, body: fn(i32) -> ()) -> () { 8 | if a < b { 9 | body(a); 10 | range(a+1, b, body) 11 | } 12 | } 13 | 14 | fn init_zero(arr: &mut [f32]) -> () { 15 | for i in range(7, 17) { 16 | arr(i) = 1337f; 17 | } 18 | } 19 | 20 | fn main() -> int { 21 | init_zero(~[42: f32]); 22 | if true { 0 } else { 1 } 23 | } 24 | -------------------------------------------------------------------------------- /test/codegen/land.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn g(i: int) -> bool { 4 | !(i == 0 && i == 23) || i == 42 5 | } 6 | 7 | fn main() -> int { 8 | if g(0) { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/ldg.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | extern "C" { 4 | fn __ldg[T](&T) -> T; 5 | } 6 | 7 | fn main(x: &int) -> int { 8 | __ldg(x) 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/lea_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | struct Foo { 4 | data: [i32 * 2], 5 | id: i32 6 | } 7 | 8 | fn foo() -> Foo { 9 | let mut bar: Foo; 10 | bar.id = 2323; 11 | bar.data(0) = 4242; 12 | bar 13 | } 14 | 15 | fn take_address(bar: &Foo) -> () {} 16 | 17 | fn main() -> int { 18 | let mut bar = foo(); 19 | take_address(&bar); 20 | if bar.data(0) + bar.id == 6565 { 0 } else { 1 } 21 | } 22 | -------------------------------------------------------------------------------- /test/codegen/lvalue_struct.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn iter(out: Img, body: fn(Img) -> ()) -> () { 4 | body(out) 5 | } 6 | 7 | fn main() -> int { 8 | let out = Img{data: ~[16*16:f32], width: 16, height: 16}; 9 | for out in iter(out) { 10 | out.data(23) = 42.f; 11 | } 12 | 13 | if out.data(23) == 42.f { 0 } else { 1 } 14 | }; 15 | 16 | struct Img { 17 | data : &mut[f32], 18 | width : i32, 19 | height : i32 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/codegen/match.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn forty_two() -> int; 5 | } 6 | 7 | //fn test1(i: (int, int)) -> int { 8 | //match i { 9 | //(2, 3) => 5, 10 | //(1, x) => x, 11 | //_ => 0 12 | //} 13 | //} 14 | 15 | fn test2(i: int) -> int { 16 | match i { 17 | 5 => 6, 18 | 42 => 0, 19 | _ => 3 20 | } 21 | } 22 | 23 | fn main() -> int { 24 | test2(forty_two()) 25 | /* 26 | match (test1((forty_two(), forty_two())), test2(forty_two())) { 27 | (0, 0) => 0, 28 | _ => 1, 29 | } 30 | */ 31 | } 32 | -------------------------------------------------------------------------------- /test/codegen/match_color.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn forty_two() -> int; 5 | } 6 | 7 | fn main() -> int { 8 | let x = Color::Red(forty_two()); 9 | 10 | match x { 11 | Color::Red(42) => 0, 12 | Color::Red(y) => y, 13 | Color::Green(y) => y, 14 | Color::Blue(y) => y, 15 | Color::Nil => 1, 16 | _ => 2, 17 | } 18 | } 19 | 20 | enum Color { 21 | Red(int), 22 | Green(int), 23 | Blue(int), 24 | Nil, 25 | } 26 | -------------------------------------------------------------------------------- /test/codegen/mem2reg_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | // https://github.com/AnyDSL/thorin/issues/27 4 | 5 | fn take_address(&&int) -> () {} 6 | 7 | fn main() -> int { 8 | let mut i = 23; 9 | let p = &mut i; 10 | take_address(&p); 11 | 12 | while i < 42 { 13 | (*p)++; 14 | } 15 | 16 | if i == 42 { 0 } else { 1 } 17 | } 18 | -------------------------------------------------------------------------------- /test/codegen/mem2reg_bug2.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | // https://github.com/AnyDSL/thorin/issues/27 4 | 5 | fn iterate_children(node_id: &mut i32) -> () { 6 | for call_me() { 7 | if 42 < *node_id { 8 | // Nothing to see here 9 | } 10 | } 11 | *node_id = 42; 12 | } 13 | 14 | fn call_me(body: fn() -> ()) -> () { 15 | body(); 16 | } 17 | 18 | fn main() -> int { 19 | let mut res = 42; 20 | while res < 43 { 21 | @iterate_children(&mut res); 22 | ++res; 23 | } 24 | 25 | if res == 43 { 0 } else { 1 } 26 | } 27 | -------------------------------------------------------------------------------- /test/codegen/mod.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | if (0 % 4 + 4 % 4 + 8 % 4 + 144 % 4) == 0 { 0 } else { 1 } 5 | } 6 | -------------------------------------------------------------------------------- /test/codegen/mono_range.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, b: int, body: fn(int) -> ()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a+1, b, body) 7 | } 8 | } 9 | 10 | fn main() -> int { 11 | let mut sum = 0; 12 | for i in range(23, 42) { 13 | sum++; 14 | } 15 | if sum == 19 { 0 } else { 1 } 16 | } 17 | -------------------------------------------------------------------------------- /test/codegen/mutable_load.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | struct S { 3 | a: int, 4 | b: int 5 | } 6 | extern "thorin" { fn sizeof[T]() -> int; } 7 | extern "C" { fn impala_memmove(&mut [u8], &[u8], i64) -> (); } 8 | 9 | fn main() -> int { 10 | let mut s = S { a: 0, b: 1 }; 11 | let mut a = s.a; 12 | let b = s.b; 13 | impala_memmove(&mut a as &mut[u8], &s.a as &[u8], sizeof[int]() as i64); 14 | if ?b { 0 } else { 1 } 15 | } 16 | -------------------------------------------------------------------------------- /test/codegen/nested_functions.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn g(mut i: int) -> int { 4 | fn f(j: int) -> int { 5 | i + j 6 | } 7 | ++i; 8 | f(i) 9 | } 10 | 11 | fn main() -> int { 12 | if g(1) == 4 { 0 } else { 1 } 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/nullptr.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn println(&[u8]) -> (); 5 | } 6 | 7 | static int_nullptr = 0 as ∫ 8 | 9 | fn check(p: &int) -> () { 10 | if p == int_nullptr { 11 | println("null"); 12 | } else { 13 | println("not null"); 14 | } 15 | } 16 | 17 | fn main() -> int { 18 | let mut p = int_nullptr; 19 | check(p); 20 | p = ~42; 21 | check(p); 22 | if true { 0 } else { 1 } 23 | } 24 | -------------------------------------------------------------------------------- /test/codegen/nullptr.out: -------------------------------------------------------------------------------- 1 | null 2 | not null 3 | -------------------------------------------------------------------------------- /test/codegen/or.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(a: bool, b: bool) -> bool { 4 | a || b 5 | } 6 | 7 | fn main() -> int { 8 | let mut res = 0; 9 | if foo(false, false) { 10 | res += 1; 11 | } 12 | if foo(false, true) { 13 | res += 2; 14 | } 15 | if foo( true, false) { 16 | res += 4; 17 | } 18 | if foo( true, true) { 19 | res += 8; 20 | } 21 | if res == 14 { 0 } else { 1 } 22 | } 23 | -------------------------------------------------------------------------------- /test/codegen/parallel.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn main() -> int { 4 | let mut i = 0; 5 | 6 | for x in parallel(2, 0, 4) { 7 | i++; 8 | } 9 | 10 | if i != 0 { 0 } else { 1 } 11 | } 12 | -------------------------------------------------------------------------------- /test/codegen/param_elimination_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | struct Thing { 4 | count: i32 5 | } 6 | 7 | fn is_empty(thing: &Thing) -> bool { 8 | thing.count == 0 9 | } 10 | 11 | fn call_me(body: fn() -> ()) -> () { 12 | body(); 13 | } 14 | 15 | fn test(i: &mut i32, body: fn() -> ()) -> () { 16 | call_me(|| { 17 | body(); 18 | *i = 42; 19 | }); 20 | } 21 | 22 | extern fn cleanup_bug(i: &mut i32) -> () { 23 | for test(i) { 24 | let thing = Thing { count: 42 }; 25 | 26 | // Only breaks if it is a 'while' loop 27 | while !is_empty(&thing) { 28 | } 29 | } 30 | } 31 | 32 | fn main() -> int { 33 | if true { 0 } else { 1 } 34 | } 35 | -------------------------------------------------------------------------------- /test/codegen/partial_eval_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | // https://github.com/AnyDSL/thorin/issues/24 4 | fn @max(a: f32, b: f32) -> f32 { 5 | if a > b { a } else { b } 6 | } 7 | 8 | fn main() -> int { 9 | let mut t0_y : f32; 10 | let t0 = max(t0_y, t0_y); 11 | 0 12 | } 13 | -------------------------------------------------------------------------------- /test/codegen/poly_id.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn id[T](x: T) -> T { 4 | x 5 | } 6 | 7 | fn main() -> int { 8 | if id[i32](23) == 23 { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/poly_sort.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn range(a: int, b: int, body: fn (int) -> ()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a + 1, b, body) 7 | } 8 | } 9 | 10 | fn sort[T](a: &mut [T], n: int, cmp: fn (T, T) -> bool) -> () { 11 | for i in range(1, n) { 12 | let elem = a(i); 13 | let mut j = i; 14 | 15 | while j > 0 && cmp(elem, a(j-1)) { 16 | a(j) = a(j - 1); 17 | j--; 18 | } 19 | a(j) = elem; 20 | } 21 | } 22 | 23 | fn main() -> int { 24 | let mut array = [100, 205, 190, 510, 42, 700, 300, 800]; 25 | sort[int](&mut array, 8, |x, y| x < y); 26 | if array(0) == 42 { 0 } else { 1 } 27 | } 28 | -------------------------------------------------------------------------------- /test/codegen/poly_sq.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn sq[T](mul: fn(T, T) -> T, val: T) -> T { 4 | mul(val, val) 5 | } 6 | 7 | fn main() -> int { 8 | if sq[i32](|a, b| a * b, 4) == 16 { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/poly_type_arg.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | extern "thorin" { 4 | fn reserve_shared[T](i32) -> &[3][T]; 5 | fn nvvm(i32, (i32, i32, i32), (i32, i32, i32), fn() -> ()) -> (); 6 | } 7 | 8 | fn main() -> i32 { 9 | with nvvm(0, (1, 1, 1), (1, 1, 1)) @{ 10 | let shared = reserve_shared[f32](1); // adding 'mut' works 11 | } 12 | 13 | 0 14 | } 15 | -------------------------------------------------------------------------------- /test/codegen/power.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn @(?n) power(a: int, n: int) -> int { 4 | if n == 0 { 5 | 1 6 | } else if n % 2 == 0 { 7 | let b = power(a, n / 2); 8 | b * b 9 | } else { 10 | a * power(a, n - 1) 11 | } 12 | } 13 | 14 | fn main() -> int { 15 | if power(3, 4) == 81 { 0 } else { 1 } 16 | } 17 | -------------------------------------------------------------------------------- /test/codegen/power_half.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn @(?n) power(a: half, n: int) -> half { 4 | if n == 0 { 5 | 1h 6 | } else if n % 2 == 0 { 7 | let b = power(a, n / 2); 8 | b * b 9 | } else { 10 | a * power(a, n - 1) 11 | } 12 | } 13 | 14 | fn main() -> int { 15 | let power4 = |a: half| -> half power(a, 4); 16 | if power(3h, 4) == 81h { 0 } else { 1 } 17 | } 18 | -------------------------------------------------------------------------------- /test/codegen/primes.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn primes[T](n: int, t: T, body: fn(int, T) -> T) -> T { 4 | if n < 2 { 5 | return(t) 6 | } 7 | let ret = return; 8 | 9 | body(2, t, |t| -> ! { 10 | fn loop(i: int, t: T) -> ! { 11 | fn inner_loop(j: int) -> ! { 12 | if j < i { 13 | if i % j == 0 { 14 | loop(i + 1, t) 15 | } else { 16 | inner_loop(j + 1) 17 | } 18 | } 19 | body(i, t, |t| -> ! loop(i+1, t)) 20 | } 21 | if (i < n) { 22 | inner_loop(2) 23 | } else { 24 | return(t) 25 | } 26 | } 27 | loop(3, t) 28 | }) 29 | } 30 | 31 | fn main() -> int { 32 | let main_ret = return; 33 | let x:int = primes(50, 0, 34 | |p, result, next| -> ! next(result + p)); 35 | 36 | primes(100, (0, 42), 37 | |p, result, next| -> ! { 38 | next(result) 39 | }, 40 | |result : (int, int)| -> ! { 41 | main_ret(if result(0) == 0 { 0 } else { 1 }) 42 | } 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /test/codegen/primes_for.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | /* 4 | foreach that adds all primes smaller than 40 5 | expected result: 197 6 | */ 7 | fn primes(n: int, body: fn(int) -> ()) -> () { 8 | let ret = return; 9 | if n < 2 { 10 | ret() 11 | } 12 | 13 | body(2, || -> ! { 14 | fn loop(i: int) -> ! { 15 | fn inner_loop(j: int) -> ! { 16 | if j < i { 17 | if i % j == 0 { 18 | loop(i + 1) 19 | } else { 20 | inner_loop(j + 1) 21 | } 22 | } else { 23 | body(i, || -> ! loop(i+1)) 24 | } 25 | } 26 | if i < n { 27 | inner_loop(2) 28 | } else { 29 | ret() 30 | } 31 | } 32 | loop(3) 33 | }) 34 | } 35 | 36 | fn main() -> int { 37 | let mut result = 0; 38 | for p in primes(40) { 39 | result += p; 40 | } 41 | if result == 197 { 0 } else { 1 } 42 | } 43 | -------------------------------------------------------------------------------- /test/codegen/range.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | trait Iterator { 4 | fn inc(self: Self) -> Self; 5 | fn lt(self: Self, other: Self) -> bool; 6 | } 7 | 8 | impl Iterator for int { 9 | fn inc(self: int) -> int { self + 1 } 10 | fn lt(self: int, other: int) -> bool { self < other } 11 | } 12 | 13 | fn range[I: Iterator](a: I, b: I, body: fn(I)->()) -> () { 14 | if (a.lt(b)) { 15 | body(a); 16 | range(a.inc(), b, body) 17 | } else { 18 | return() 19 | } 20 | } 21 | 22 | fn main() -> int { 23 | let mut sum = 0; 24 | for i in range(0, 10) { 25 | sum += i 26 | } 27 | if sum == 45 { 0 } else { 1 } 28 | } 29 | -------------------------------------------------------------------------------- /test/codegen/range_f.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, b: int, body: fn(int)->()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a+1, b, body) 7 | } else { 8 | return() 9 | } 10 | } 11 | 12 | fn main() -> int { 13 | let mut sum = 0; 14 | fn body(i: int) -> () { 15 | sum += i 16 | } 17 | range(0, 10, body); 18 | if sum == 45 { 0 } else { 1 } 19 | } 20 | -------------------------------------------------------------------------------- /test/codegen/range_for.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, b: int, body: fn(int)->()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a+1, b, body) 7 | } 8 | } 9 | 10 | fn main() -> int { 11 | let mut sum = 0; 12 | for i in range(0, 10) { 13 | //for j in range(0, 10) { 14 | //if i == 0 { 15 | //continue() 16 | //} else if i == 1 { 17 | //break() 18 | //} else { 19 | sum += i//*j 20 | //} 21 | //} 22 | } 23 | if sum == 45 { 0 } else { 1 } 24 | } 25 | -------------------------------------------------------------------------------- /test/codegen/range_l.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, b: int, body: fn(int)->()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a+1, b, body) 7 | } else { 8 | return() 9 | } 10 | } 11 | 12 | fn main() -> int { 13 | let mut sum = 0; 14 | 15 | range(0, 10, |i| sum += i); 16 | if sum == 45 { 0 } else { 1 } 17 | } 18 | -------------------------------------------------------------------------------- /test/codegen/range_poly.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | trait Iterator { 4 | fn inc(self: Self) -> Self; 5 | fn lt(self: Self, other: Self) -> bool; 6 | } 7 | 8 | impl Iterator for i32 { 9 | fn inc(self: i32) -> i32 { self + 1 } 10 | fn lt(self: i32, other: i32) -> bool { self < other } 11 | } 12 | 13 | fn range[I: Iterator](a: I, b: I, body: fn(I)->()) -> () { 14 | if (a.lt(b)) { 15 | body(a); 16 | range(a.inc(), b, body) 17 | } else { 18 | return() 19 | } 20 | } 21 | 22 | fn main() -> int { 23 | let mut sum = 0; 24 | for i in range(0, 10) { 25 | let j: int = 26 | if i == 5 { 27 | 42 28 | } else if i == 6 { 29 | continue() 30 | } else if i == 8 { 31 | break() 32 | } else { 33 | i 34 | }; 35 | sum += j + j; 36 | } 37 | if sum == 118 { 0 } else { 1 } 38 | } 39 | -------------------------------------------------------------------------------- /test/codegen/range_unroll.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn range(a: int, b: int, body: fn(int)->()) -> () { 4 | if a < b { 5 | body(a); 6 | range(a+1, b, body) 7 | } 8 | } 9 | 10 | fn clamp(a: int, b: int) -> int { 11 | if a < b { a } else { b} 12 | } 13 | 14 | fn foo(i: int, f: fn(int, int) -> int, g: fn(int, int) -> int) -> int { 15 | g(f(i, i+1), 42) 16 | } 17 | 18 | fn main() -> int { 19 | let mut sum = 0; 20 | for i in range(0, 10) { 21 | sum += foo(i, clamp, clamp) 22 | } 23 | if sum == 45 { 0 } else { 1 } 24 | } 25 | -------------------------------------------------------------------------------- /test/codegen/ref_array_array_literal.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | 4 | static mut v0 = "elem1"; 5 | static mut v1 = "elem2"; 6 | 7 | fn main() -> int { 8 | let mut variants: [&[u8] * 2] = [(&v0) as &[u8], &v1]; 9 | 10 | 0 11 | } 12 | -------------------------------------------------------------------------------- /test/codegen/ret_assert.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | extern "thorin" { 4 | fn nvvm(int, (int, int, int), (int, int, int), fn() -> ()) -> (); 5 | } 6 | extern "device" { 7 | fn "llvm.nvvm.read.ptx.sreg.tid.x" nvvm_read_ptx_sreg_tid_x() -> i32; 8 | } 9 | 10 | fn iteration_broken(body : fn(int) -> ()) -> () { 11 | let block = (32, 4, 1); 12 | let dim = (1024, 1024, 1); 13 | nvvm(0, dim, block, || { 14 | if (nvvm_read_ptx_sreg_tid_x() < 1) { 15 | body(0); 16 | return() 17 | } 18 | }); 19 | } 20 | 21 | 22 | fn main() -> int { 23 | let size = 1024; 24 | let arr = ~[size:float]; 25 | let mut out = ~[size:float]; 26 | 27 | for x in @iteration_broken() { 28 | out(x) = arr(x); 29 | } 30 | 31 | if true { 0 } else { 1 } 32 | } 33 | -------------------------------------------------------------------------------- /test/codegen/return_in_lambda.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn g(i: int) -> int { 4 | let f = |x: int| -> int return(x+i); 5 | 6 | f(i) 7 | } 8 | 9 | fn main() -> int { 10 | if g(5) == 10 { 0 } else { 1 } 11 | } 12 | -------------------------------------------------------------------------------- /test/codegen/return_tuple.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | type Blob = (i32, i32); 4 | fn blobify(i: i32) -> Blob { 5 | (i, i) 6 | } 7 | 8 | fn main() -> int { 9 | let b = blobify(42); 10 | if b(0) + b(1) == 84 { 0 } else { 1 } 11 | } 12 | -------------------------------------------------------------------------------- /test/codegen/returning_yield.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn sum(a: int, b: int, acc: &mut int, body: fn(int) -> int) -> int { 4 | if a < b { 5 | let x = body(a); 6 | *acc = *acc + x; 7 | sum(a+1, b, acc, body, return) 8 | } 9 | *acc + 23 10 | } 11 | 12 | fn main() -> int { 13 | let mut acc = 0; 14 | let res = for i in sum(0, 13, &mut acc) { 15 | if i == 19 { 16 | break(77) 17 | } else { 18 | i 19 | } 20 | }; 21 | if res == 101 { 0 } else { 1 } 22 | } 23 | -------------------------------------------------------------------------------- /test/codegen/retvoid.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn f() -> () { 4 | } 5 | 6 | fn main() -> int { 7 | f(); 8 | if true { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/rvalue_ref.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(i: &int) -> int { 4 | *i 5 | } 6 | 7 | fn main() -> int { 8 | if foo(&42) == 42 { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/select.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "thorin" { 4 | fn select[T,U](T, U, U) -> U; 5 | } 6 | 7 | fn main() -> int { 8 | if select(true, 23, 42) == 23 { 0 } else { 1 } 9 | } 10 | -------------------------------------------------------------------------------- /test/codegen/shift.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn f(buf: &mut [uint], width: int, x: int, v: int) -> () { 4 | buf(24*width + x) = ((v<<24) | v) as u32; 5 | } 6 | 7 | fn main() -> int { 0 } 8 | -------------------------------------------------------------------------------- /test/codegen/shift_bug.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | // https://github.com/AnyDSL/impala/issues/34 4 | fn main() -> i32 { 5 | if (1 << 31) as u32 == 0x80000000u32 { 0 } else { 1 } 6 | } 7 | -------------------------------------------------------------------------------- /test/codegen/simd_lea.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn mask_store(i: simd[bool * 4], src: simd[int * 4], dst: &mut simd[int * 4]) -> () { 4 | if i(0) { dst(0) = src(0) } 5 | if i(1) { dst(1) = src(1) } 6 | if i(2) { dst(2) = src(2) } 7 | if i(3) { dst(3) = src(3) } 8 | } 9 | 10 | fn main() -> int { 11 | let mask = simd[true, false, true, false]; 12 | let mut v = simd[1, 2, 3, 4]; 13 | let w = simd[4, 5, 6, 7]; 14 | mask_store(mask, w, &mut v); 15 | if v(0) + v(1) + v(2) + v(3) == 16 { 0 } else { 1 } 16 | } 17 | -------------------------------------------------------------------------------- /test/codegen/simple.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn f(i: int) -> int { 4 | let mut a; 5 | if i == 1 { 6 | a = 23 7 | } else { 8 | a = 42 9 | } 10 | a 11 | } 12 | 13 | fn main() -> int { 14 | if (f(0) + f(1)) == 65 { 0 } else { 1 } 15 | } 16 | -------------------------------------------------------------------------------- /test/codegen/sizeof.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "thorin" { 4 | fn sizeof[T]() -> i64; 5 | } 6 | 7 | fn @foo() -> i64 { 8 | sizeof[i32]() 9 | } 10 | 11 | fn main() -> i32 { 12 | if foo() == 4i64 { 0 } else { 1 } 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/static.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | static mut x = 3; 5 | static y = 4; 6 | foo += 17; 7 | ++x; 8 | if (foo + bar + foobar + x + y) == 132 { 0 } else { 1 } 9 | } 10 | 11 | static mut foo = 42; 12 | static bar = 23; 13 | static mut foobar = 42; 14 | -------------------------------------------------------------------------------- /test/codegen/steensgard.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn myfun(i: int) -> int { 4 | let ret = return; 5 | fn branch(cond: bool, t: fn() -> !, f: fn() -> !) -> ! { 6 | if cond { t() } else { f() } 7 | } 8 | 9 | fn switch(i: int, a: fn() -> !, b: fn() -> !, c: fn() -> !) -> ! { 10 | if i == 0 { 11 | a() 12 | } else if i == 1 { 13 | b() 14 | } else { 15 | c() 16 | } 17 | } 18 | 19 | fn x() -> ! { z() } 20 | fn y() -> ! { z() } 21 | fn z() -> ! { e() } 22 | 23 | fn b() -> ! { d() } 24 | //fn c() { e() } 25 | fn c() -> ! { branch(i == 0, x, y) } 26 | fn d() -> ! { switch(i, b, e, f) } 27 | fn e() -> ! { switch(i, d, c, f) } 28 | fn f() -> ! { ret(23) } 29 | 30 | branch(i == 0, b, c) 31 | } 32 | 33 | fn main() -> int { 34 | if myfun(2) == 23 { 0 } else { 1 } 35 | } 36 | -------------------------------------------------------------------------------- /test/codegen/string.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn println(&[u8]) -> (); 5 | } 6 | 7 | fn main() -> int { 8 | let mut s = 9 | "hellox" 10 | "world"; 11 | s(5) = ' '; 12 | println(&s); 13 | if true { 0 } else { 1 } 14 | } 15 | -------------------------------------------------------------------------------- /test/codegen/string.out: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /test/codegen/struct.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut v = Vec3{x: 1, y: 2, z: 3}; 5 | v.z += 36; 6 | if v.x + v.y + v.z == 42 { 0 } else { 1 } 7 | } 8 | 9 | struct Vec3 { 10 | x: int, 11 | y: int, 12 | z: int, 13 | } 14 | -------------------------------------------------------------------------------- /test/codegen/struct_arg.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | struct S { 4 | fun : fn(i32, fn(fn(i32) -> i32) -> ()) -> (), 5 | } 6 | 7 | static g = S { 8 | fun : fun_impl, 9 | }; 10 | 11 | fn fun_impl(N: i32, body: fn(fn(i32) -> i32) -> ()) -> () { 12 | fn idx(i: i32) -> i32 { i * N } 13 | body(idx); 14 | } 15 | 16 | fn main(p: S, N: i32, arr: &mut [f32]) -> () { 17 | for idx_hyp in p.fun(N) { 18 | arr(idx_hyp(42)) = 42.0f; 19 | arr(23) = 23.0f; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/codegen/struct_expr.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> i32 { 4 | let s = S{g: |a, b| a + b, f: |a| a}; 5 | if s.g(23, 42)- s.f(23) == 42 { 0 } else { 1 } 6 | } 7 | 8 | struct S { 9 | f: fn(i32) -> i32, 10 | g: fn(i32, i32) -> i32, 11 | } 12 | -------------------------------------------------------------------------------- /test/codegen/subtype.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn foo(a: &[int]) -> int { 4 | a(2) 5 | } 6 | 7 | fn main() -> int { 8 | let mut a = [0, 1, 2, 3]; 9 | if foo(&a) == 2 { 0 } else { 1 } 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/subtyping_struct_expr.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | struct S { 4 | data: &[f32] 5 | } 6 | 7 | fn main() -> i32 { 8 | let s = S { data : ~[5:f32] }; 9 | 0 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/system_f_problem.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn id[T](a: T) -> T { a } 4 | 5 | fn main() -> int { 6 | let foo = id[fn[T](T)->T](id); 7 | if true { 0 } else { 1 } 8 | } 9 | -------------------------------------------------------------------------------- /test/codegen/trait_impls.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | // TODO this example is not semantically correct because method overloading is prohibited! (=>int cannot implement A and B together) 4 | 5 | trait B { 6 | fn a(self: Self) -> f32; 7 | } 8 | 9 | trait A { 10 | fn a(self: Self) -> int; 11 | fn b(self: Self) -> bool; 12 | } 13 | 14 | impl A for int { 15 | fn a(self: int) -> int { 42 } 16 | fn b(self: int) -> bool { true } 17 | } 18 | 19 | impl B for int { 20 | fn a(self: int) -> f32 { 23.f } 21 | } 22 | 23 | fn f[T: A + B, U: A](a: T, b: U) -> int { 24 | f(a, b) 25 | } 26 | 27 | fn main() -> int { 28 | if f(23, 42) == 0 { 0 } else { 1 } 29 | } 30 | -------------------------------------------------------------------------------- /test/codegen/trait_impls.out: -------------------------------------------------------------------------------- 1 | TODO 2 | -------------------------------------------------------------------------------- /test/codegen/typeof.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let i = 23; 5 | let j: typeof(i) = i; 6 | let k: typeof(42) = 42; 7 | if i == j { 0 } else { 1 } 8 | } 9 | -------------------------------------------------------------------------------- /test/codegen/vcycle.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern "C" { 4 | fn print_int(int) -> (); 5 | } 6 | fn range(a: int, b: int, body: fn(int) -> ()) -> () { 7 | if a < b { 8 | body(a); 9 | range(a+1, b, body) 10 | } 11 | } 12 | fn sort(num: int, arr: &mut [i64]) -> () { 13 | // insertion sort 14 | for i in range(1, num) { 15 | let x = arr(i); 16 | let mut j = i; 17 | while j > 0 && arr(j-1) > x { 18 | arr(j) = arr(j-1); 19 | j = j - 1; 20 | } 21 | arr(j) = x; 22 | } 23 | } 24 | 25 | fn main() -> int { 26 | let levels = 2; 27 | let mut times = ~[2:i64]; 28 | 29 | fn @vcycle_dsl_intern(level: int) -> () { 30 | sort(2, times); 31 | if level == levels-1 { 32 | print_int(times(1) as int); 33 | } else { 34 | vcycle_dsl_intern(level+1); 35 | times(level) = 0i64; 36 | } 37 | } 38 | vcycle_dsl_intern(0); 39 | if true { 0 } else { 1 } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /test/codegen/void_tailcall.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | // https://github.com/AnyDSL/thorin/issues/51 4 | extern fn h(mut n: int) -> () { g(n) } 5 | extern fn i(mut n: int) -> () { g(n) } 6 | extern fn g(mut n: int) -> () { 7 | let mut i = 0; 8 | while i < n { i = i*3 + 2*i + 5*i; } 9 | } 10 | extern fn f(mut n: int, ret: fn() -> !) -> ! { 11 | g(n, ret) 12 | } 13 | 14 | fn main() -> int { 0 } 15 | -------------------------------------------------------------------------------- /test/codegen/while.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn f(i: int) -> int { 4 | let mut sum = 0; 5 | while i < 42 { 6 | ++sum; 7 | if sum == 1 { 8 | continue() 9 | } else if sum == 2 { 10 | break() 11 | } 12 | sum += 3 13 | } 14 | sum 15 | } 16 | 17 | fn main() -> int { 18 | if f(38) == 2 { 0 } else { 1 } 19 | } 20 | -------------------------------------------------------------------------------- /test/codegen/while_fold1.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut sum = 0; 5 | while true { 6 | ++sum; 7 | if sum == 1 { 8 | continue() 9 | } else if sum == 2 { 10 | break() 11 | } 12 | sum += 3 13 | } 14 | if sum == 2 { 0 } else { 1 } 15 | } 16 | -------------------------------------------------------------------------------- /test/codegen/while_fold2.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut sum = 0; 5 | while false { 6 | ++sum; 7 | if sum == 1 { 8 | continue() 9 | } else if sum == 2 { 10 | break() 11 | } 12 | sum += 3 13 | } 14 | if sum == 0 { 0 } else { 1 } 15 | } 16 | -------------------------------------------------------------------------------- /test/codegen/while_nested.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn main() -> int { 4 | let mut i = 0; 5 | let mut sum = 0; 6 | while true { 7 | while i < 23 { 8 | ++i; 9 | ++sum; 10 | } 11 | i = 0; 12 | if sum >= 42 { 13 | break() 14 | } 15 | } 16 | if sum == 46 { 0 } else { 1 } 17 | } 18 | -------------------------------------------------------------------------------- /test/codegen/while_seq.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | extern fn f(n: int) -> int { 4 | let mut sum = 0; 5 | while sum < n { 6 | ++sum; 7 | } 8 | while sum < n { 9 | ++sum; 10 | } 11 | sum 12 | } 13 | 14 | fn main() -> int { 15 | if f(5) == 5 { 0 } else { 1 } 16 | } 17 | -------------------------------------------------------------------------------- /test/codegen/while_true.impala: -------------------------------------------------------------------------------- 1 | // codegen broken 2 | 3 | fn main() -> int { 4 | let mut i = 0; 5 | while true { 6 | i++; 7 | } 8 | 9 | if true { 0 } else { 1 } 10 | } 11 | -------------------------------------------------------------------------------- /test/codegen/zip.impala: -------------------------------------------------------------------------------- 1 | // codegen 2 | 3 | fn primes(n: int, yield: fn(int) -> !) -> ! { 4 | if (n < 2) { 5 | yield(2) 6 | } 7 | 8 | fn loop(i : int) -> ! { 9 | fn inner_loop(j : int) -> ! { 10 | if (j < i) { 11 | if (i % j == 0) { 12 | loop(i + 1) 13 | } else { 14 | inner_loop(j + 1) 15 | } 16 | } 17 | yield(i) 18 | } 19 | inner_loop(2) 20 | } 21 | loop(n) 22 | } 23 | 24 | fn count(n : int, yield : fn(int) -> !) -> ! { 25 | yield(n+1) 26 | } 27 | 28 | fn zip(zipper : fn(int, int) -> int, generate1 : fn(int) -> int, generate2 : fn(int) -> int, yield : fn(int) -> ()) -> ! { 29 | fn loop(i : int) -> ! { 30 | yield(zipper(generate1(i), generate2(i)), || -> ! { loop(i + 1) }) 31 | } 32 | loop(0) 33 | } 34 | 35 | fn main(ret : fn(int) -> !) -> ! { 36 | fn zipper(a : int, b : int) -> int { a + b } 37 | zip(zipper, primes, count, |i : int, next : fn() -> ! | -> ! { 38 | if (i > 24) { 39 | ret(if i == 26 { 0 } else { 1 }) 40 | } else { 41 | next() 42 | } 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /test/fix_output.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | impala type_inference/positive/${1}.impala --emit-annotated > type_inference/positive/${1}.output 3 | -------------------------------------------------------------------------------- /test/partial_eval/ackermann.impala: -------------------------------------------------------------------------------- 1 | fn @(?m & ?n) a(m: int, n: int) -> int { 2 | if m == 0 { 3 | n + 1 4 | } else if n == 0 { 5 | a(m-1, 1) 6 | } else { 7 | a(m-1, a(m, n-1)) 8 | } 9 | } 10 | 11 | fn main(i: int) -> int { 12 | a(3, 3) 13 | } 14 | -------------------------------------------------------------------------------- /test/partial_eval/array.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?b) range(a: int, b: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | @@body(a); 4 | range(a+1, b, body) 5 | } 6 | } 7 | 8 | fn main(arr: &mut [int]) -> int { 9 | //let mut sum_xxx = 42; 10 | for i in range(0, 3) { 11 | //sum_xxx += arr(i); 12 | arr(i+1) = i; 13 | } 14 | arr(42) 15 | } 16 | -------------------------------------------------------------------------------- /test/partial_eval/blocked_loop.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?b) range_step(a: int, b: int, step: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | @@body(a); 4 | range_step(a+step, b, step, body) 5 | } 6 | } 7 | 8 | fn @(?length) blocked_loop(length: int, get_block_size: fn(int) -> int, body: fn(int, fn(int) -> !) -> !) -> int { 9 | fn @(?cur_level) blocked_iter(cur_level: int, i: int, N: int) -> int { 10 | let block_size = get_block_size(cur_level); 11 | if block_size <= 0 { 12 | @@body(i) 13 | } else { 14 | let mut res = 0; 15 | for ii in range_step($i, $N, block_size) { 16 | res += blocked_iter(cur_level + 1, ii, block_size); 17 | } 18 | res 19 | } 20 | } 21 | 22 | blocked_iter(1, 0, length) 23 | } 24 | 25 | fn main(i: int) -> int { 26 | fn @get_block_size(i: int) -> int { 27 | if i == 0 { 4096 } 28 | else if i == 1 { 2048 } 29 | else if i == 2 { 1024 } 30 | else if i == 3 { 256 } 31 | else { 0 } 32 | } 33 | 34 | blocked_loop(8192, get_block_size, |i| i) 35 | } 36 | -------------------------------------------------------------------------------- /test/partial_eval/double_loop.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?b) range(a: int, b: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | @@body(a); 4 | range(a+1, b, body) 5 | } 6 | } 7 | 8 | fn foo(a: int, b: int) -> int { 9 | let mut res1 = 0; 10 | for i in range(7, a) { 11 | res1 += 666; 12 | } 13 | 14 | let mut res2 = 0; 15 | for i in range(17, b) { 16 | res2 += 3333; 17 | } 18 | 19 | 17 + res2 20 | } 21 | 22 | fn main(i: int) -> int { 23 | foo(i, 19) 24 | } 25 | -------------------------------------------------------------------------------- /test/partial_eval/dynamic_fun.impala: -------------------------------------------------------------------------------- 1 | fn @ fun1(a: i32, b: i32) -> i32 { a } 2 | fn @ fun2(a: i32, b: i32) -> i32 { b } 3 | 4 | fn main(flag: bool) -> i32 { 5 | let fun = if flag { fun1 } else { fun2 }; 6 | fun(47, 11) 7 | } 8 | -------------------------------------------------------------------------------- /test/partial_eval/logic_operator.impala: -------------------------------------------------------------------------------- 1 | fn @ fun() -> bool { false } 2 | 3 | fn main() -> int { 4 | if fun() && true { 1 } else { 0 } 5 | } 6 | -------------------------------------------------------------------------------- /test/partial_eval/mut_slot_loops.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?b) range(a: int, b: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | @@body(a); 4 | range(a+1, b, body) 5 | } 6 | } 7 | 8 | fn @foo(n: int) -> int { 9 | let mut m = 0; 10 | let mut res = 0; 11 | for i in range(0, n) { 12 | m++; 13 | for j in range(0, m) { 14 | res++; 15 | } 16 | } 17 | res 18 | } 19 | 20 | fn main() -> int { 21 | foo(2) 22 | } 23 | -------------------------------------------------------------------------------- /test/partial_eval/nested.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?z) range(a: int, z: int, body: fn(int)->()) -> () { 2 | if a < z { 3 | @@body(a); 4 | range(a+1, z, body) 5 | } 6 | } 7 | 8 | fn @ foo(a: int, b: int) -> int { 9 | let mut res1 = 0; 10 | let mut res2 = 0; 11 | 12 | for i in range(0, a) { 13 | res1 += 4; 14 | for i in range(0, b) { 15 | res2 += 3333; 16 | } 17 | } 18 | 19 | res1 + res2 20 | } 21 | 22 | fn main(i: int) -> int { 23 | foo(i, 10) 24 | } 25 | -------------------------------------------------------------------------------- /test/partial_eval/nested_loop.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?b) range(a: int, b: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | @@body(a); 4 | range(a+1, b, body) 5 | } 6 | } 7 | 8 | fn iteration_bounds(body: fn(int, int, int) -> ()) -> () { 9 | let Bounds2D = [[ 0, 1, 2, 3], 10 | [ 4, 5, 6, 7], 11 | [ 8, 9, 10, 11], 12 | [12, 13, 14, 15]]; 13 | 14 | for region in range(0, 4) { 15 | let bounds = Bounds2D(region); 16 | for y in range($bounds(2), $bounds(3)) { 17 | @@body(0, y, region); 18 | } 19 | } 20 | } 21 | 22 | fn main(i: int) -> () { 23 | for x, y, region in iteration_bounds() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/partial_eval/power.impala: -------------------------------------------------------------------------------- 1 | fn power(a: int, @mut b: int) -> int { 2 | let mut result = 1; 3 | while (b != 0) { 4 | result *= a; 5 | --b; 6 | } 7 | 8 | result 9 | } 10 | 11 | fn main(i: int) -> int { 12 | let power4 = |a: int| -> int power(a, 4); 13 | power4(i) + power(3, 4) 14 | } 15 | -------------------------------------------------------------------------------- /test/partial_eval/range.impala: -------------------------------------------------------------------------------- 1 | fn range(a: int, b: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | body(a); 4 | range(a+1, b, body) 5 | } 6 | } 7 | 8 | fn main(i: int) -> int { 9 | let mut sum = 0; 10 | for i in range(0, 3) { 11 | sum += i; 12 | } 13 | sum 14 | } 15 | -------------------------------------------------------------------------------- /test/partial_eval/runblock.impala: -------------------------------------------------------------------------------- 1 | fn power(a: int, @mut b: int) -> int { 2 | let mut result = 1; 3 | while (b != 0) { 4 | result *= a; 5 | --b; 6 | } 7 | 8 | result 9 | } 10 | 11 | fn main(i: int) -> int { 12 | { 13 | let x = power(i, 4); 14 | } 15 | 42 16 | } 17 | -------------------------------------------------------------------------------- /test/partial_eval/sorting_net_batcher.impala: -------------------------------------------------------------------------------- 1 | fn @batcher_sort(n: int, cmp_swap: fn (int, int) -> ()) -> () { 2 | fn @merge(i: int, len: int, r: int) -> () { 3 | let step = r * 2; 4 | if step < len { 5 | merge(i, len, step); 6 | merge(i + r, len, step); 7 | for j in range_step(i + r, i + len - r, step) { 8 | // Remove comparators for non-existing elements 9 | if j < n && j + r < n { 10 | cmp_swap(j, j + r) 11 | } 12 | } 13 | } else { 14 | // idem 15 | if i < n && i + r < n { 16 | cmp_swap(i, i + r); 17 | } 18 | } 19 | } 20 | 21 | fn @sort(i: int, len: int) -> () { 22 | if len > 1 { 23 | let m = len / 2; 24 | sort(i, m); 25 | sort(i + m, m); 26 | merge(i, len, 1) 27 | } 28 | } 29 | 30 | // Compute closest power of two 31 | let p = 1 << ilog2(n); 32 | sort(0, p) 33 | } 34 | 35 | fn @ilog2(i: int) -> int { 36 | fn @(?i) ilog2_helper(i: int, p: int) -> int { 37 | if i <= 1 { 38 | p 39 | } else { 40 | ilog2_helper(i / 2, p + 1) 41 | } 42 | } 43 | ilog2_helper(i, 0) 44 | } 45 | 46 | fn @(?a & ?b) range_step(a: int, b: int, @ c: int, @ body: fn (int) -> ()) -> () { 47 | if a < b { 48 | @@body(a); 49 | range_step(a + c, b, c, body, return) 50 | } 51 | } 52 | 53 | fn @validate(arr: &[int * 8]) -> bool { 54 | let mut prev = arr(0); 55 | fn @rec(i: int) -> bool { 56 | if i < 8 { 57 | if prev <= arr(i) { 58 | prev = arr(i); 59 | rec(i+1) 60 | } else { 61 | false 62 | } 63 | } else { 64 | true 65 | } 66 | } 67 | rec(1) 68 | } 69 | 70 | fn main() -> bool { 71 | let mut array = [2, 6, 4, 8, 1, 3, 7, 5]; 72 | batcher_sort(8, @ |i, j| { 73 | let vi = array(i); 74 | let vj = array(j); 75 | if (vi > vj) { 76 | array(i) = vj; 77 | array(j) = vi; 78 | } 79 | }); 80 | validate(array) 81 | } 82 | -------------------------------------------------------------------------------- /test/partial_eval/sorting_net_bose_nelson.impala: -------------------------------------------------------------------------------- 1 | extern "thorin" { 2 | fn select[T, U](T, U, U) -> U; 3 | } 4 | 5 | fn @bose_nelson_sort(n: int, cmp_swap: fn (int, int) -> ()) -> () { 6 | fn @p_star(i: int, len: int) -> () { 7 | if len > 1 { 8 | let m = len / 2; 9 | p_star(i, m); 10 | p_star((i + m), (len - m)); 11 | p_bracket(i, m, (i + m), (len - m)); 12 | } 13 | } 14 | 15 | fn @p_bracket(i1: int, len1: int, i2: int, len2: int) -> () { 16 | if len1 == 1 && len2 == 1 { 17 | cmp_swap(i1, i2); 18 | } else if len1 == 1 && len2 == 2 { 19 | cmp_swap(i1, i2 + 1); 20 | cmp_swap(i1, i2); 21 | } else if len1 == 2 && len2 == 1 { 22 | cmp_swap(i1, i2); 23 | cmp_swap(i1 + 1, i2); 24 | } else { 25 | let a = len1 / 2; 26 | let b = select(len1 % 2 != 0, len2 / 2, (len2 + 1) / 2); 27 | p_bracket(i1, a, i2, b); 28 | p_bracket((i1 + a), (len1 - a), (i2 + b), (len2 - b)); 29 | p_bracket((i1 + a), (len1 - a), i2, b); 30 | } 31 | } 32 | 33 | p_star(0, n) 34 | } 35 | 36 | fn @validate(arr: &[int * 8]) -> bool { 37 | let mut prev = arr(0); 38 | fn @rec(i: int) -> bool { 39 | if i < 8 { 40 | if prev <= arr(i) { 41 | prev = arr(i); 42 | rec(i+1) 43 | } else { 44 | false 45 | } 46 | } else { 47 | true 48 | } 49 | } 50 | rec(1) 51 | } 52 | 53 | fn main() -> bool { 54 | let mut array = [2, 6, 4, 8, 1, 3, 7, 5]; 55 | bose_nelson_sort(8, @ |i, j| { 56 | let vi = array(i); 57 | let vj = array(j); 58 | if (vi > vj) { 59 | array(i) = vj; 60 | array(j) = vi; 61 | } 62 | }); 63 | validate(array) 64 | } 65 | 66 | -------------------------------------------------------------------------------- /test/partial_eval/two_loops.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?z) range(a: int, z: int, body: fn(int)->()) -> () { 2 | if a < z { 3 | body(a); 4 | range(a+1, z, body) 5 | } 6 | } 7 | 8 | fn @ foo(a: int, b: int) -> int { 9 | let mut res1 = 0; 10 | for i in range(0, a) { 11 | res1 += 4; 12 | } 13 | 14 | let mut res2 = 0; 15 | for i in range(0, b) { 16 | res2 += 3333; 17 | } 18 | 19 | res1 + res2 20 | } 21 | 22 | fn main(i: int) -> int { 23 | foo(i, 10) 24 | } 25 | -------------------------------------------------------------------------------- /test/partial_eval/unroll.impala: -------------------------------------------------------------------------------- 1 | fn @(?a & ?b) range(a: int, b: int, body: fn(int, fn() -> !) -> !) -> () { 2 | if a < b { 3 | body(a); 4 | range(a+1, b, body) 5 | } 6 | } 7 | 8 | fn foo(i: int) -> float { 9 | if i == 0 { 23.f } else { 42.f } 10 | } 11 | 12 | fn main(n: int) -> () { 13 | let arr = ~[n: float]; 14 | 15 | let unroll = 100; 16 | for i in range(0, unroll) @{ 17 | arr(0) = foo(i); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/sema/negative/address_of_val_array.out: -------------------------------------------------------------------------------- 1 | address_of_val_array.impala:2 col 6 - 8: error: lvalue required as unary '&' operand 2 | address_of_val_array.impala:2 col 5 - 8: warning: statement with no effect 3 | -------------------------------------------------------------------------------- /test/sema/negative/anonymous.impala: -------------------------------------------------------------------------------- 1 | fn foo(_: int, a: int) -> int { 2 | a + _ 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/anonymous.out: -------------------------------------------------------------------------------- 1 | anonymous.impala:2 col 9: error: identifier '_' is reverserved for anonymous declarations 2 | -------------------------------------------------------------------------------- /test/sema/negative/array_equality.impala: -------------------------------------------------------------------------------- 1 | extern "C" { fn puts(&[u8]) -> (); } 2 | 3 | fn main() -> () { 4 | let i = [1, 2, 3, 4]; 5 | let j = [1, 2, 3, 4]; 6 | if i == j { 7 | puts("equal") 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /test/sema/negative/assign.impala: -------------------------------------------------------------------------------- 1 | fn foo() -> () { 2 | let mut x = 23_u64; 3 | x += 42; 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/negative/assign_no_lvalue.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | 17 = 5; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/assign_no_lvalue.out: -------------------------------------------------------------------------------- 1 | assign_no_lvalue.impala:2 col 5 - 6: error: lvalue required for assignment 2 | -------------------------------------------------------------------------------- /test/sema/negative/bool_literal.impala: -------------------------------------------------------------------------------- 1 | fn f() -> int { 2 | true 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/char.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let a = 'ab'; 3 | let b = '\g'; 4 | let c = '\hx'; 5 | let d = '\nx'; 6 | let e = ''; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/char.out: -------------------------------------------------------------------------------- 1 | char.impala:2 col 13 - 16: error: multi-character character constant 2 | char.impala:3 col 13 - 16: error: unknown escape sequence '\g' 3 | char.impala:4 col 13 - 17: error: unknown escape sequence '\h' 4 | char.impala:4 col 13 - 17: error: multi-character character constant 5 | char.impala:5 col 13 - 17: error: multi-character character constant 6 | char.impala:6 col 13 - 14: error: empty character constant 7 | -------------------------------------------------------------------------------- /test/sema/negative/constrain_check.impala: -------------------------------------------------------------------------------- 1 | fn get_direction(dir: i32, body: fn(i64) -> ()) -> () { 2 | (|a| body(a)) (1) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/constrain_check.out: -------------------------------------------------------------------------------- 1 | constrain_check.impala:2 col 15: error: incompatible types: 'i32' and 'i64' found as argument type 2 | -------------------------------------------------------------------------------- /test/sema/negative/cps_call.impala: -------------------------------------------------------------------------------- 1 | fn main() -> int { 2 | fn f(a: int, b: int, c: int) { 3 | f(1, 2) 4 | } 5 | 42 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/cps_call.out: -------------------------------------------------------------------------------- 1 | cps_call.impala:3 col 9 - 15: error: missing last argument to call continuation 2 | -------------------------------------------------------------------------------- /test/sema/negative/def_array.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let todo:[int*1] = [0, 0]; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/fn_neq1.impala: -------------------------------------------------------------------------------- 1 | trait A {} 2 | trait B {} 3 | 4 | fn f[T: A + B](a: T) -> int { 5 | 42 6 | } 7 | 8 | fn g[T: A + B](a: T) -> int { 9 | 42 10 | } 11 | 12 | fn foo(x: fn[T: A](T) -> int) -> int { 13 | 23 14 | } 15 | 16 | fn main() -> () { 17 | foo(f); 18 | foo(g); 19 | } 20 | -------------------------------------------------------------------------------- /test/sema/negative/fn_neq1.out: -------------------------------------------------------------------------------- 1 | fn_neq1.impala:17 col 9: error: mismatched types: expected 'fn[T: A](T) -> i32' but found 'fn[T: A + B](T) -> i32' as argument type 2 | fn_neq1.impala:18 col 9: error: mismatched types: expected 'fn[T: A](T) -> i32' but found 'fn[T: A + B](T) -> i32' as argument type 3 | -------------------------------------------------------------------------------- /test/sema/negative/if01.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: int = if (true) { 3 | return() 4 | } else { 5 | return() 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/if01.out: -------------------------------------------------------------------------------- 1 | if01.impala:2 col 18 - 6 col 5: error: mismatched types: expected 'i32' but found '' as initialization type 2 | -------------------------------------------------------------------------------- /test/sema/negative/impl_bounds.impala: -------------------------------------------------------------------------------- 1 | trait T[A] {} 2 | trait U[B] {} 3 | impl[C: U[C]] T[C] for int {} 4 | fn f[D: T[D]](x: D) -> D { x } 5 | fn main() -> () { 6 | f[int](42); 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/impl_bounds.out: -------------------------------------------------------------------------------- 1 | impl_bounds.impala:6 col 5 - 14: error: 'i32' (instance for 'D') does not implement bound 'T[i32]' 2 | -------------------------------------------------------------------------------- /test/sema/negative/incorrect_param_types.impala: -------------------------------------------------------------------------------- 1 | fn f(i: for, int, k) -> () { 2 | i + j; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/incorrect_param_types.out: -------------------------------------------------------------------------------- 1 | incorrect_param_types.impala:1 col 9 - 11: error: expected type, got 'for' 2 | incorrect_param_types.impala:1 col 19: error: 'k' not found in current scope 3 | incorrect_param_types.impala:2 col 9: error: 'j' not found in current scope 4 | incorrect_param_types.impala:3 col 1: error: mismatched types: expected 'i32' but found '()' as return type 5 | -------------------------------------------------------------------------------- /test/sema/negative/indefinite_array.impala: -------------------------------------------------------------------------------- 1 | fn foo(x: [i32]) -> [i32] { 2 | let y = [23: i32]; 3 | let z = ([23: i32], 23); 4 | let mut w: (i32, [i32]); 5 | y 6 | } 7 | 8 | struct S { 9 | S: [i32] 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/negative/indefinite_array.out: -------------------------------------------------------------------------------- 1 | indefinite_array.impala:1 col 11 - 15: error: indefinite array '[i32]' not allowed as parameter type because its size is statically unknown; use a definite array or a pointer to an indefinite array instead 2 | indefinite_array.impala:1 col 21 - 25: error: indefinite array '[i32]' not allowed as element type in a function type because its size is statically unknown; use a definite array or a pointer to an indefinite array instead 3 | indefinite_array.impala:2 col 9: error: indefinite array '[i32]' not allowed as type for a local variable because its size is statically unknown; use a definite array or a pointer to an indefinite array instead 4 | indefinite_array.impala:3 col 14 - 22: error: indefinite array '[i32]' not allowed as type for an element in a tuple expression because its size is statically unknown; use a definite array or a pointer to an indefinite array instead 5 | indefinite_array.impala:4 col 22 - 26: error: indefinite array '[i32]' not allowed as element type in a tuple because its size is statically unknown; use a definite array or a pointer to an indefinite array instead 6 | indefinite_array.impala:4 col 9 - 27: warning: variable 'w' declared mutable but variable is never written to 7 | indefinite_array.impala:9 col 5 - 12: error: indefinite array '[i32]' not allowed as type for a struct field because its size is statically unknown; use a definite array or a pointer to an indefinite array instead 8 | -------------------------------------------------------------------------------- /test/sema/negative/int_literal.impala: -------------------------------------------------------------------------------- 1 | fn f() -> bool { 2 | 4 3 | } -------------------------------------------------------------------------------- /test/sema/negative/lazy_analysis1.impala: -------------------------------------------------------------------------------- 1 | fn f[A: T](x:A) -> A { 2 | x 3 | } 4 | trait T { 5 | fn tf(A) -> A; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/lazy_analysis2.impala: -------------------------------------------------------------------------------- 1 | fn f(x: int) -> int { 2 | g() 3 | } 4 | fn g() -> int { 5 | x 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/lazy_analysis2.out: -------------------------------------------------------------------------------- 1 | lazy_analysis2.impala:5 col 4: error: 'x' not found in current scope 2 | -------------------------------------------------------------------------------- /test/sema/negative/literal_overflow.impala: -------------------------------------------------------------------------------- 1 | fn check_literals() -> () { 2 | let x : i16 = 0x8000i16; 3 | let y : i32 = 0x80000000i32; 4 | let z : i64 = 0x8000000000000000i64; 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/negative/literal_overflow.out: -------------------------------------------------------------------------------- 1 | literal_overflow.impala:2 col 19 - 27: error: literal out of range for type 'i16' 2 | literal_overflow.impala:3 col 19 - 31: error: literal out of range for type 'i32' 3 | literal_overflow.impala:4 col 19 - 39: error: literal out of range for type 'i64' 4 | -------------------------------------------------------------------------------- /test/sema/negative/literals.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | { let i: u8 = 0u16; } 3 | { let i: u16 = 0u32; } 4 | { let i: u32 = 0u64; } 5 | { let i: u64 = 0u8; } 6 | { let i: i8 = 0i16; } 7 | { let i: i16 = 0i32; } 8 | { let i: i32 = 0i64; } 9 | { let i: i64 = 0i8; } 10 | { let f: f32 = 0f64; } 11 | { let f: f64 = 0f32; } 12 | { let i: i32 = 0b_; } 13 | { let i: i32 = 0b_0; } 14 | { let i: i32 = 0b2; } 15 | { let i: i32 = 0o_; } 16 | { let i: i32 = 0o_0; } 17 | { let i: i32 = 0o8; } 18 | { let i: i32 = 0x_; } 19 | { let i: i32 = 0x_0; } 20 | { let i: i32 = 0x8; } 21 | } 22 | -------------------------------------------------------------------------------- /test/sema/negative/literals.out: -------------------------------------------------------------------------------- 1 | literals.impala:12 col 23: error: invalid constant '0b_' 2 | literals.impala:14 col 22: error: invalid constant '0b' 3 | literals.impala:14 col 22: error: expected ';', got '2' while parsing the end of an let statement 4 | literals.impala:15 col 23: error: invalid constant '0o_' 5 | literals.impala:17 col 22: error: invalid constant '0o' 6 | literals.impala:17 col 22: error: expected ';', got '8' while parsing the end of an let statement 7 | literals.impala:18 col 23: error: invalid constant '0x_' 8 | literals.impala:2 col 20 - 23: error: mismatched types: expected 'u8' but found 'u16' as initialization type 9 | literals.impala:3 col 20 - 23: error: mismatched types: expected 'u16' but found 'u32' as initialization type 10 | literals.impala:4 col 20 - 23: error: mismatched types: expected 'u32' but found 'u64' as initialization type 11 | literals.impala:5 col 20 - 22: error: mismatched types: expected 'u64' but found 'u8' as initialization type 12 | literals.impala:6 col 20 - 23: error: mismatched types: expected 'i8' but found 'i16' as initialization type 13 | literals.impala:7 col 20 - 23: error: mismatched types: expected 'i16' but found 'i32' as initialization type 14 | literals.impala:8 col 20 - 23: error: mismatched types: expected 'i32' but found 'i64' as initialization type 15 | literals.impala:9 col 20 - 22: error: mismatched types: expected 'i64' but found 'i8' as initialization type 16 | literals.impala:10 col 20 - 23: error: mismatched types: expected 'f32' but found 'f64' as initialization type 17 | literals.impala:11 col 20 - 23: error: mismatched types: expected 'f64' but found 'f32' as initialization type 18 | literals.impala:14 col 22: warning: statement with no effect 19 | literals.impala:17 col 22: warning: statement with no effect 20 | -------------------------------------------------------------------------------- /test/sema/negative/literals_too_large.impala: -------------------------------------------------------------------------------- 1 | fn main() -> int { 2 | let int_max = 2147483647; 3 | let int_max_plus_one = 2147483648; 4 | let int_max_plus_ = 0xff_ff_ff_ff_ff; 5 | 0 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/lvalue_inc_dec.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let mut i = 23; 3 | (i++)++; 4 | (++i)++; 5 | (i--)--; 6 | (--i)--; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/lvalue_inc_dec.out: -------------------------------------------------------------------------------- 1 | lvalue_inc_dec.impala:3 col 6 - 8: error: lvalue required for postfix '++' 2 | lvalue_inc_dec.impala:4 col 6 - 8: error: lvalue required for postfix '++' 3 | lvalue_inc_dec.impala:5 col 6 - 8: error: lvalue required for postfix '--' 4 | lvalue_inc_dec.impala:6 col 6 - 8: error: lvalue required for postfix '--' 5 | -------------------------------------------------------------------------------- /test/sema/negative/methods01.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | impl T for i32 {} 3 | 4 | fn main() -> () { 5 | let b: bool = (5).m(); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/methods02.impala: -------------------------------------------------------------------------------- 1 | trait T[A] { 2 | fn m(Self, A) -> A; 3 | } 4 | 5 | impl T[bool] for i32 { 6 | fn m(x: i32, a: bool) -> bool { a } 7 | } 8 | 9 | fn main() -> () { 10 | let b: int = (5).m(5); 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/negative/missing_typevar.impala: -------------------------------------------------------------------------------- 1 | fn f(x:A) -> () {} 2 | -------------------------------------------------------------------------------- /test/sema/negative/missing_typevar.out: -------------------------------------------------------------------------------- 1 | missing_typevar.impala:1 col 8: error: 'A' not found in current scope 2 | -------------------------------------------------------------------------------- /test/sema/negative/mutual_trait_refs.impala: -------------------------------------------------------------------------------- 1 | // these traits are not implementable 2 | trait S[A: T[int]] {} 3 | trait T[B: S[int]] {} 4 | 5 | // ...or are they? 6 | impl S[int] for int {} 7 | impl T[int] for int {} 8 | -------------------------------------------------------------------------------- /test/sema/negative/mutual_trait_refs.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/sema/negative/mutual_trait_refs.out -------------------------------------------------------------------------------- /test/sema/negative/no_ret1.impala: -------------------------------------------------------------------------------- 1 | fn f(r: fn(int)) { 2 | let x: int = r(4); 3 | x 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/negative/no_ret1.out: -------------------------------------------------------------------------------- 1 | no_ret1.impala:2 col 18 - 21: error: mismatched types: expected 'i32' but found '' as initialization type 2 | -------------------------------------------------------------------------------- /test/sema/negative/repeated_definite_array_expr03.impala: -------------------------------------------------------------------------------- 1 | fn main() -> int { 2 | let x: [int*2] = [0, ..3]; 3 | x(0) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/negative/repeated_definite_array_expr03.out: -------------------------------------------------------------------------------- 1 | repeated_definite_array_expr03.impala:2 col 22 - 29: error: mismatched types: expected '[i32 * 2]' but found '[i32 * 3]' as initialization type 2 | -------------------------------------------------------------------------------- /test/sema/negative/return1.impala: -------------------------------------------------------------------------------- 1 | fn iid(i: int) -> int { 2 | i 3 | } 4 | 5 | fn main() -> () { 6 | let x: bool = iid(5); 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/return1.out: -------------------------------------------------------------------------------- 1 | return1.impala:6 col 19 - 24: error: return type 'i32' does not match expected type 'bool' 2 | -------------------------------------------------------------------------------- /test/sema/negative/return2.impala: -------------------------------------------------------------------------------- 1 | fn f() -> int { 2 | true 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/return2.out: -------------------------------------------------------------------------------- 1 | return2.impala:2 col 4 - 7: error: mismatched types: expected 'i32' but found 'bool' as return type 2 | -------------------------------------------------------------------------------- /test/sema/negative/scoping1.impala: -------------------------------------------------------------------------------- 1 | fn fun(f: fn[A](A)->A, g: fn[A](A)->A, x:A) -> () {} 2 | -------------------------------------------------------------------------------- /test/sema/negative/scoping1.out: -------------------------------------------------------------------------------- 1 | scoping1.impala:1 col 42: error: 'A' not found in current scope 2 | -------------------------------------------------------------------------------- /test/sema/negative/scoping2.impala: -------------------------------------------------------------------------------- 1 | fn fun(f: fn[A](A)->A) -> A {} 2 | -------------------------------------------------------------------------------- /test/sema/negative/scoping2.out: -------------------------------------------------------------------------------- 1 | scoping2.impala:1 col 27: error: 'A' not found in current scope 2 | -------------------------------------------------------------------------------- /test/sema/negative/simd.impala: -------------------------------------------------------------------------------- 1 | fn wrong_type1() -> float { 2 | simd[1.0f, 2.0f, 3.0f, 4.0f] 3 | } 4 | 5 | fn wrong_type2(id: int) -> simd[float * 4] { 6 | simd[1.0f, 2.0f, 3.0f, 4.0f](id) 7 | } 8 | 9 | fn wrong_type3() -> simd[float * 4] { 10 | simd[1.0f, 2.0f, 3.0f, 4.0f] + simd[1, 2, 3, 4] 11 | } 12 | 13 | fn wrong_type4() -> bool { 14 | simd[true, true, true, true] & true 15 | } 16 | 17 | fn wrong_type5() -> simd[bool * 4] { 18 | simd[true, true, true, true] ^ simd[true, false, true, false, true] 19 | } 20 | 21 | fn wrong_type6() -> simd[bool * 4] { 22 | [true, false, true, false] 23 | } 24 | -------------------------------------------------------------------------------- /test/sema/negative/simd.out: -------------------------------------------------------------------------------- 1 | simd.impala:2 col 5 - 32: error: mismatched types: expected 'f32' but found 'simd[f32 * 4]' as return type 2 | simd.impala:6 col 5 - 36: error: mismatched types: expected 'simd[f32 * 4]' but found 'f32' as return type 3 | simd.impala:10 col 36 - 51: error: mismatched types: expected 'simd[f32 * 4]' but found 'simd[i32 * 4]' as return type 4 | simd.impala:14 col 5 - 32: error: mismatched types: expected 'bool' but found 'simd[bool * 4]' 5 | simd.impala:18 col 36 - 71: error: mismatched types: expected 'simd[bool * 4]' but found 'simd[bool * 5]' as return type 6 | simd.impala:22 col 5 - 30: error: mismatched types: expected 'simd[bool * 4]' but found '[bool * 4]' as return type 7 | -------------------------------------------------------------------------------- /test/sema/negative/static.impala: -------------------------------------------------------------------------------- 1 | static mut foo = 42; 2 | static bar = foo; 3 | static mut foobar = foo; 4 | 5 | extern fn f(i: int) -> () { 6 | static mut j = i; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/string.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let s = "\g"; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/string.out: -------------------------------------------------------------------------------- 1 | string.impala:2 col 13 - 16: error: unknown escape sequence '\g' 2 | -------------------------------------------------------------------------------- /test/sema/negative/struct01.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let s = S { x: 5 }; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/struct02.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | x: bool 3 | } 4 | 5 | fn f() -> S { 6 | S { x: 5 } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/struct03.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | x: int, 3 | x: bool 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/negative/struct04.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | x: x 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/struct05.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | 3 | struct S[A:T] { 4 | x: A 5 | } 6 | 7 | fn f() -> S { 8 | S[int] { x: 5 } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/negative/struct06.impala: -------------------------------------------------------------------------------- 1 | struct S[A] { 2 | x: A 3 | } 4 | 5 | fn f() -> S { 6 | S[int, bool] { x: 5 } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/struct07.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | x: int, 3 | y: bool 4 | } 5 | 6 | fn f() -> S { 7 | S { x: 5 } 8 | } 9 | 10 | fn f() -> S { 11 | S { x: 5, y: true, z: 7 } 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/negative/struct08.impala: -------------------------------------------------------------------------------- 1 | struct S[X] { x: X } 2 | 3 | fn main() -> () { 4 | let s: S[bool] = S[int] { x: 5 }; 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/negative/struct08.out: -------------------------------------------------------------------------------- 1 | struct08.impala:4 col 23 - 25: error: expected different argument for type parameter 'X': expected 'bool' but found 'i32' 2 | struct08.impala:4 col 33: error: mismatched types: expected 'bool' but found 'i32' as initialization type for field 'x' 3 | -------------------------------------------------------------------------------- /test/sema/negative/struct09.impala: -------------------------------------------------------------------------------- 1 | struct S[X] { x: X } 2 | struct T[X] { x: X } 3 | 4 | fn main() -> () { 5 | let s: T[bool] = S[int] { x: 5 }; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/struct09.out: -------------------------------------------------------------------------------- 1 | struct09.impala:5 col 21 - 35: error: mismatched types: expected 'T[bool]' but found 'S[i32]' as initialization type 2 | -------------------------------------------------------------------------------- /test/sema/negative/struct_equality.impala: -------------------------------------------------------------------------------- 1 | extern "C" { fn puts(&[u8]) -> (); } 2 | 3 | struct Lollipops { 4 | i : int 5 | } 6 | 7 | fn main() -> () { 8 | let i = Lollipops { i : 42 }; 9 | let j = Lollipops { i : 42 }; 10 | if i == j { 11 | puts("equal") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/sema/negative/struct_names.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | a : i32 3 | } 4 | struct T { 5 | a : i32 6 | } 7 | 8 | fn getT(a: i32) -> T { getS(a) } 9 | fn getS(a: i32) -> S { S { a : a } } 10 | 11 | fn main(i: i32) -> i32 { 12 | getT(i).a 13 | } 14 | -------------------------------------------------------------------------------- /test/sema/negative/struct_names.out: -------------------------------------------------------------------------------- 1 | struct_names.impala:8 col 22 - 32: error: mismatched types: expected 'T' but found 'S' as return type 2 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping1.impala: -------------------------------------------------------------------------------- 1 | fn f(r: fn(f64)->()) -> () { 2 | r(5) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping1.out: -------------------------------------------------------------------------------- 1 | subtyping1.impala:2 col 6: error: mismatched types: expected 'f64' but found 'i32' as argument type 2 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping2.impala: -------------------------------------------------------------------------------- 1 | fn f(r: fn(f32)->()) -> () { 2 | r(4) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping2.out: -------------------------------------------------------------------------------- 1 | subtyping2.impala:2 col 6: error: mismatched types: expected 'f32' but found 'i32' as argument type 2 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping3_ptr.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x : int = 5; 3 | let y : &bool = ~x; 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping3_ptr.out: -------------------------------------------------------------------------------- 1 | subtyping3_ptr.impala:3 col 22: error: mismatched types: expected 'bool' but found 'i32' 2 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping4_array.impala: -------------------------------------------------------------------------------- 1 | fn main(x: [int * 2]) -> () { 2 | let y : [bool] = x; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping4_array.out: -------------------------------------------------------------------------------- 1 | subtyping4_array.impala:2 col 22: error: mismatched types: expected '[bool]' but found '[i32 * 2]' as initialization type 2 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping5.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U {} 3 | 4 | fn main(x: fn[A: T]([int*2], A)) -> () { 5 | let y : fn[A: U]([int], A) = x; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/subtyping5.out: -------------------------------------------------------------------------------- 1 | subtyping5.impala:5 col 34: error: mismatched types: expected 'fn[A: U]([i32], A)' but found 'fn[A: T]([i32 * 2], A)' as initialization type 2 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits1.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> Self; 3 | } 4 | trait U : T {} 5 | 6 | impl U for i32 { 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits1.out: -------------------------------------------------------------------------------- 1 | super_traits1.impala:6 col 1 - 7 col 1: error: Must implement method 'f' 2 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits2.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> Self; 3 | } 4 | trait U : T { 5 | fn f(self: Self) -> Self; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits2.out: -------------------------------------------------------------------------------- 1 | super_traits2.impala:5 col 5 - 29: error: a method with this name already exists in a super trait. 2 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits3.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> (); 3 | } 4 | trait U { 5 | fn f(self: Self) -> (); 6 | } 7 | trait V : T, U {} 8 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits3.out: -------------------------------------------------------------------------------- 1 | super_traits3.impala:7 col 1 - 17: error: conflicting method name in super traits: 'f' 2 | -------------------------------------------------------------------------------- /test/sema/negative/super_traits4.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn f(self: Self) -> B; 3 | } 4 | trait U : T {} 5 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls1.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> i32; 3 | } 4 | impl T for bool { 5 | fn f(self: i32) -> i32 { 6 | self 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls2.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> (); 3 | } 4 | impl T for bool { 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls3.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> i32; 3 | } 4 | impl T for bool { 5 | fn f(self: bool) -> bool { self } 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls4.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | impl T for i32 {} 3 | impl T for i32 {} 4 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls5.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> (); 3 | } 4 | trait U { 5 | fn f(self: Self) -> (); 6 | } 7 | 8 | // f implemented two times! 9 | impl T for bool { 10 | fn f(self: bool) -> () {} 11 | } 12 | impl U for bool { 13 | fn f(self: bool) -> () {} 14 | } 15 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls5.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/sema/negative/trait_impls5.out -------------------------------------------------------------------------------- /test/sema/negative/trait_impls6.impala: -------------------------------------------------------------------------------- 1 | trait T[A] { 2 | fn f(self: Self) -> (); 3 | } 4 | 5 | impl T for int { 6 | fn f(self: int) -> () {} 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/trait_impls6.out: -------------------------------------------------------------------------------- 1 | trait_impls6.impala:5 col 6: error: wrong number of instances for bound type variables of trait 'T': 0 for 1 2 | -------------------------------------------------------------------------------- /test/sema/negative/unreachable.impala: -------------------------------------------------------------------------------- 1 | fn f() -> i32 { 2 | return(17); 3 | 42 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/negative/unreachable.out: -------------------------------------------------------------------------------- 1 | unreachable.impala:2 col 5 - 14: error: expression does not return; subsequent statements are unreachable 2 | -------------------------------------------------------------------------------- /test/sema/negative/while.impala: -------------------------------------------------------------------------------- 1 | fn foo(x: int) -> () { 2 | while x { 3 | 23 4 | } 5 | 6 | let foo = if x { 23 } else { 42 }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num1.impala: -------------------------------------------------------------------------------- 1 | fn f(x:int, g:fn(int)->int) -> int { 2 | g() 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num1.out: -------------------------------------------------------------------------------- 1 | wrong_arg_num1.impala:2 col 4 - 6: error: too few arguments: 0 for 1 2 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num2.impala: -------------------------------------------------------------------------------- 1 | fn f(x:int, g:fn(int)->int) -> int { 2 | g(x, x) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num3.impala: -------------------------------------------------------------------------------- 1 | fn f(x:int, g:fn(int)->int) -> int { 2 | g(x, x, x) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num3.out: -------------------------------------------------------------------------------- 1 | wrong_arg_num3.impala:2 col 4 - 13: error: too many arguments: 3 for 1 2 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num4.impala: -------------------------------------------------------------------------------- 1 | fn f(x:int, g:fn[A](A)->A) -> int { 2 | g[int, bool](x) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num5.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | return(4) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_num5.out: -------------------------------------------------------------------------------- 1 | wrong_arg_num5.impala:2 col 5 - 13: error: too many arguments: 1 for 0 2 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_arg_type.impala: -------------------------------------------------------------------------------- 1 | fn myf(x: bool, f: fn(int)->bool) -> bool { 2 | f(x) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_condition_type.impala: -------------------------------------------------------------------------------- 1 | fn main(i: int) -> () { 2 | if (i) {} 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_condition_type.out: -------------------------------------------------------------------------------- 1 | wrong_condition_type.impala:2 col 9: error: mismatched types: expected boolean type but found 'i32' as if condition 2 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_return.impala: -------------------------------------------------------------------------------- 1 | fn main() - > i32 { 2 | 0 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_return.out: -------------------------------------------------------------------------------- 1 | wrong_return.impala:1 col 11: error: expected block expression, got '-' while parsing body of function 2 | wrong_return.impala:1 col 11: error: expected module item, got '-' while parsing module contents 3 | wrong_return.impala:1 col 9: error: cannot infer a return type, maybe you forgot to mark the function with '-> !'? 4 | wrong_return.impala:1 col 9: error: mismatched types: expected '' but found '()' as return type 5 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_return1.impala: -------------------------------------------------------------------------------- 1 | fn f(x : int) -> bool { 2 | x 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/negative/wrong_return2.impala: -------------------------------------------------------------------------------- 1 | fn f[A, B](x:A) -> B { 2 | x 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/address01.impala: -------------------------------------------------------------------------------- 1 | fn f(&int) -> () {} 2 | 3 | fn main() -> () { 4 | let mut i: int = 42; 5 | f(&i) 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/address02.impala: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | fn foo(&int) -> (); 3 | } 4 | 5 | fn main() -> () { 6 | let mut i: int = 42; 7 | foo(&i) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/array_access01.impala: -------------------------------------------------------------------------------- 1 | fn main(i: int) -> int { 2 | let mut a: [int*3] = [0, 1, 2]; 3 | a(i+1) = 5; 4 | a(i) 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/positive/block.impala: -------------------------------------------------------------------------------- 1 | fn main(i: i32) -> i32 { 2 | let j: i32 = 0; 3 | { 4 | let j: i32 = 0; 5 | { /* test a stmt-like block-expr for parsing */ } 6 | j 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/bound_checking1.impala: -------------------------------------------------------------------------------- 1 | trait S {} 2 | trait T[A : S] {} 3 | fn f[B:T[C]+S, C:T[B]+S](x:B, y:C) -> () {} 4 | -------------------------------------------------------------------------------- /test/sema/positive/bound_checking2.impala: -------------------------------------------------------------------------------- 1 | trait U {} 2 | trait T[A : U] {} 3 | 4 | struct S[C: U] { c: C } 5 | 6 | fn f[B:U](x:S[B]) -> () {} 7 | -------------------------------------------------------------------------------- /test/sema/positive/bound_checking3.impala: -------------------------------------------------------------------------------- 1 | trait U {} 2 | trait T[A : U] {} 3 | 4 | impl[C: U] T[C] for int {} 5 | -------------------------------------------------------------------------------- /test/sema/positive/bound_checking4.impala: -------------------------------------------------------------------------------- 1 | trait U {} 2 | trait T[A : U] {} 3 | 4 | struct S[B: U] { x: B } 5 | 6 | impl[C: U] U for S[C] {} 7 | fn g[D:T[S[E]], E: U](x: D) -> () {} 8 | -------------------------------------------------------------------------------- /test/sema/positive/break.impala: -------------------------------------------------------------------------------- 1 | fn range(a: int, z: int, body: fn(int)->()) -> () { 2 | if a < z { 3 | body(a); 4 | range(a+1, z, body) 5 | } 6 | } 7 | 8 | fn main(n : int) -> int { 9 | let mut res : int = 0; 10 | for i in range(0, n) { 11 | if i*i > 42 { 12 | break() 13 | } 14 | res += i; 15 | } 16 | res 17 | } 18 | -------------------------------------------------------------------------------- /test/sema/positive/call_simple.impala: -------------------------------------------------------------------------------- 1 | fn f(x:int, g:fn(int) -> bool) -> bool { 2 | g(x) 3 | } -------------------------------------------------------------------------------- /test/sema/positive/cast.impala: -------------------------------------------------------------------------------- 1 | fn main(i: int) -> float { 2 | (i+17) as float 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/complex_fn_type1.impala: -------------------------------------------------------------------------------- 1 | trait T[A] {} 2 | fn f[B:T[C], C:T[B]](x:B, y:C) -> () {} 3 | -------------------------------------------------------------------------------- /test/sema/positive/continuation.impala: -------------------------------------------------------------------------------- 1 | extern fn f(i : int, ret : fn(int) -> !) -> ! { 2 | g(3) + 5 3 | } 4 | 5 | extern fn g(i : int, ret : fn(int) -> !) -> ! { 6 | f(i, ret) 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/cross_struct.impala: -------------------------------------------------------------------------------- 1 | struct A { 2 | i: int, 3 | b: &B 4 | } 5 | 6 | struct B { 7 | i: int, 8 | a: &A 9 | } 10 | 11 | fn main() -> () { 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/positive/double_continue.impala: -------------------------------------------------------------------------------- 1 | fn range(a: int, z: int, body: fn(int)->()) -> () { 2 | if a < z { 3 | body(a); 4 | range(a+1, z, body) 5 | } 6 | } 7 | 8 | fn main(n : int) -> () { 9 | for i in range(0, n) { 10 | if i == 42 { 11 | continue() 12 | } else { 13 | continue() 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sema/positive/elseif.impala: -------------------------------------------------------------------------------- 1 | fn main(i: int) -> int { 2 | if i == -1 { 3 | 1 4 | } else if i == -2 { 5 | 2 6 | } else if i == -3 { 7 | 3 8 | } else if i == -4 { 9 | 4 10 | } else { 11 | 5 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/sema/positive/empty.impala: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/sema/positive/empty.impala -------------------------------------------------------------------------------- /test/sema/positive/extern.impala: -------------------------------------------------------------------------------- 1 | extern fn f(i: int) -> int { i+1 } 2 | extern fn g(i: int) -> int { i+2 } 3 | 4 | extern "C" { 5 | fn x(int) -> int; 6 | fn y(float) -> float; 7 | fn z(i8, i16, i32) -> (i8, i16, i32); 8 | } 9 | 10 | fn main(i: int) -> () { 11 | f(g(x(i))); 12 | y(42.f); 13 | let tuple = z(1_i8, 2_i16, 3_i32); 14 | } 15 | -------------------------------------------------------------------------------- /test/sema/positive/field_infer.impala: -------------------------------------------------------------------------------- 1 | fn blurb(baz: &mut int) -> () { 2 | *baz = 42 3 | } 4 | 5 | fn test(stuff: &mut Stuff) -> () { 6 | blurb(&mut stuff.thing.blah); 7 | } 8 | 9 | struct Stuff { 10 | thing: Thingy 11 | } 12 | 13 | struct Thingy { 14 | blah: int 15 | } 16 | 17 | -------------------------------------------------------------------------------- /test/sema/positive/float.impala: -------------------------------------------------------------------------------- 1 | fn f() -> float { 23.f } 2 | fn d() -> double { 42.0 } 3 | -------------------------------------------------------------------------------- /test/sema/positive/fn_equal1.impala: -------------------------------------------------------------------------------- 1 | trait A {} 2 | trait B {} 3 | 4 | fn f[T: A + B, U: A](a: T, b: U) -> int { 5 | 42 6 | } 7 | 8 | fn g[T: A + B, U: A](a: T, b: U) -> int { 9 | 42 10 | } 11 | 12 | fn foo(x: fn[T: A + B, U: A](T, U) -> int) -> int { 13 | 23 14 | } 15 | 16 | fn main() -> () { 17 | foo(f); 18 | foo(g); 19 | } 20 | -------------------------------------------------------------------------------- /test/sema/positive/fn_expr.impala: -------------------------------------------------------------------------------- 1 | fn f(x:fn(i32)->i32) -> i32 { 2 | x(52) 3 | } 4 | fn g() -> i32 { 5 | f(|i:i32|->i32 i) 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/if01.impala: -------------------------------------------------------------------------------- 1 | fn f(x : int, y : int, b : bool) -> int { 2 | if b { x } else { y } 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/if02.impala: -------------------------------------------------------------------------------- 1 | fn round_up(num : int, multiple : int) -> int { 2 | if multiple == 0 { return(num) } 3 | 4 | let rem = num % multiple; 5 | if rem == 0 { num } else { num + multiple - rem } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/sema/positive/if03.impala: -------------------------------------------------------------------------------- 1 | fn f() -> int { 2 | if (true) { 3 | return(4) 4 | } else { 5 | 5 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if04.impala: -------------------------------------------------------------------------------- 1 | fn f() -> int { 2 | if (true) { 3 | return(4) 4 | } else { 5 | return(5) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if05.impala: -------------------------------------------------------------------------------- 1 | fn f() -> int { 2 | if (true) { 3 | 4 4 | } else { 5 | return(5) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if06.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | if (true) { 3 | 4 4 | } else { 5 | return() 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if07.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | if (true) { 3 | return() 4 | } else { 5 | 3 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if08.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: int = if (true) { 3 | return() 4 | } else { 5 | 5 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if09.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: int = if (true) { 3 | 5 4 | } else { 5 | return() 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/if10.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: int = if (true) { 3 | return() 4 | } else { 5 | 5 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/impl_after_usage1.impala: -------------------------------------------------------------------------------- 1 | fn myf(f: fn[A:T](A) -> A) -> i32 { 2 | f[i32](4) 3 | } 4 | impl T for i32 {} 5 | trait T {} 6 | -------------------------------------------------------------------------------- /test/sema/positive/impl_after_usage2.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn neg(self: Self) -> Self; 3 | } 4 | impl T for bool { 5 | fn neg(self: bool) -> bool { if self { false } else { true } } 6 | } 7 | 8 | impl bool { 9 | fn f(self: bool) -> bool { self.neg() } 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/int_is_int32.impala: -------------------------------------------------------------------------------- 1 | fn f(x:int) -> i32 { 2 | x 3 | } 4 | fn g(x:i32) -> int { 5 | x 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/lambda.impala: -------------------------------------------------------------------------------- 1 | extern fn f(a : int) -> int { 2 | let mut i : int = 22; 3 | let j : int = 22; 4 | 5 | let g : fn(int) -> int = |k : int| -> int { 6 | fn z(x : int) -> int { x } 7 | i + j + a + z(k) 8 | }; 9 | 10 | i = 23; 11 | 12 | if a == 0 { 13 | g(23) 14 | } else { 15 | g(g(42)) 16 | } 17 | } 18 | 19 | extern fn g(i : int) -> int { 20 | (|j : int| -> int { j + 42 + i })(23) 21 | } 22 | 23 | fn foo(h : fn(int, fn (int) -> !) -> !) -> int { 24 | h(24) 25 | } 26 | 27 | extern fn bar(a : int) -> int { 28 | let k : fn(int) -> int = |b : int| -> int a + b; 29 | foo(k) 30 | } 31 | -------------------------------------------------------------------------------- /test/sema/positive/lazy_analysis1.impala: -------------------------------------------------------------------------------- 1 | fn myf[A : T[int]](x : A) -> A { 2 | x 3 | } 4 | trait T[A] {} 5 | -------------------------------------------------------------------------------- /test/sema/positive/let1.impala: -------------------------------------------------------------------------------- 1 | fn f() -> i32 { 2 | let x:i32 = 4; 3 | x 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/let2.impala: -------------------------------------------------------------------------------- 1 | fn f[A](a: A) -> A { 2 | let x:A = a; 3 | x 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/let3.impala: -------------------------------------------------------------------------------- 1 | trait Foo { 2 | fn bar(self: Self) -> (); 3 | } 4 | 5 | fn f[A: Foo](a: A) -> () { 6 | a.bar(); 7 | let x:A = a; 8 | x.bar(); 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/positive/literals.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | { let u: u32 = 42u; } 3 | { let i: i8 = 0i8; } 4 | { let i: i16 = 0i16; } 5 | { let i: i32 = 0i32; } 6 | { let i: i64 = 0i64; } 7 | { let i: u8 = 0u8; } 8 | { let i: u16 = 0u16; } 9 | { let i: u32 = 0u32; } 10 | { let i: u64 = 0u64; } 11 | { let f: f32 = 0f32; } 12 | { let f: f64 = 0f64; } 13 | { let i: i32 = 0b01; } 14 | { let i: i32 = 0b0_1111; } 15 | { let i: i32 = 0b01_; } 16 | { let i: i32 = 0b01; } 17 | { let i: i32 = 0o0_1234567; } 18 | { let i: i32 = 0o01234567_; } 19 | { let i: i64 = 0x0_123456789abcdefi64; } 20 | { let i: i64 = 0x0123456789abcdef_i64; } 21 | { let f: f64 = 1e1; } 22 | { let f: f64 = 1e-1; } 23 | { let f: f64 = 1e+1; } 24 | { let f: f64 = 1.7e1; } 25 | { let f: f64 = 1.8e-1; } 26 | { let f: f64 = 1.9e+1; } 27 | { let f: f64 = 1.7e_4; } 28 | { let f: f64 = 1.8e-_5; } 29 | { let f: f64 = 1.9e+_6; } 30 | { let f: f64 = 1.1_2_3_; } 31 | { let f: f32 = 1.1_2_3_f32; } 32 | { let f: f32 = 1.1_2_3_e+16f; } 33 | } 34 | -------------------------------------------------------------------------------- /test/sema/positive/literals1.impala: -------------------------------------------------------------------------------- 1 | fn f1(r: fn(i32)->()) -> () { 2 | r(4) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/literals2.impala: -------------------------------------------------------------------------------- 1 | fn f1(r: fn(bool)->()) -> () { 2 | r(true) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/literals3.impala: -------------------------------------------------------------------------------- 1 | fn f1(r: fn(bool)->()) -> () { 2 | r(false) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/literals4.impala: -------------------------------------------------------------------------------- 1 | fn f1(r: fn(f64)->()) -> () { 2 | r(4.0) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/map.impala: -------------------------------------------------------------------------------- 1 | struct ListElem[A] { 2 | val: A, 3 | next: ~ListElem[A] 4 | } 5 | 6 | fn map[B, C](f: fn(B)->C, l: &ListElem[B]) -> &ListElem[C] { 7 | if (l == null) { 8 | null 9 | } else { 10 | ListElem[C] { val: f(l.val), next: map(f, l.next) } 11 | } 12 | } 13 | 14 | fn main() -> &ListElem[i32] { 15 | let l1: ListElem[i32] = ListElem[i32] { val: 2, next: null }; 16 | let l2: ListElem[i32] = ListElem[i32] { val: 2, next: l1 }; 17 | map[i32, i32](|x:i32| -> i32 x+1, l2) 18 | } 19 | -------------------------------------------------------------------------------- /test/sema/positive/methods1.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> i32; 3 | } 4 | fn g[A:T](x: A) -> i32 { 5 | x.f() 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/methods2.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> i32; 3 | } 4 | impl T for bool { 5 | fn f(self: bool) -> i32 { 6 | if (self) { 7 | 1 8 | } else { 9 | 0 10 | } 11 | } 12 | } 13 | fn g() -> i32 { 14 | true.f() + false.f() 15 | } 16 | -------------------------------------------------------------------------------- /test/sema/positive/methods3.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn f(self: Self, b: B) -> B; 3 | } 4 | fn g[C, D:T[C]](c: C, d: D) -> C { 5 | d.f(c) 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/methods4.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn f(self: Self, b: B) -> B; 3 | } 4 | fn g[C, D:T[C]](c: C, d: D) -> C { 5 | d.f(c) 6 | } 7 | fn h[E:T[i32]](e: E) -> i32 { 8 | g[i32, E](42, e) 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/positive/methods5.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn f(self: Self, b: B) -> B; 3 | } 4 | fn g[C, D:T[C]](c: C, d: D) -> C { 5 | d.f(c) 6 | } 7 | fn h[E:T[i32]](e: E) -> i32 { 8 | g[i32, E](42, e) 9 | } 10 | 11 | impl T[i32] for bool { 12 | fn f(self: bool, b: i32) -> i32 { b } 13 | } 14 | fn i() -> i32 { 15 | h[bool](true) 16 | } 17 | -------------------------------------------------------------------------------- /test/sema/positive/methods6.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn conv(self: Self) -> B; 3 | } 4 | 5 | fn f[C: T[C]](c: C) -> C { 6 | c.conv().conv() 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/methods7.impala: -------------------------------------------------------------------------------- 1 | trait T[A] { 2 | fn m(Self, A) -> A; 3 | } 4 | 5 | impl T[bool] for int { 6 | fn m(x: int, a: bool) -> bool { a } 7 | } 8 | 9 | impl T[int] for int { 10 | fn m(x: int, a: int) -> int { a } 11 | } 12 | 13 | fn main() -> () { 14 | let b: bool = (5).m(true); 15 | let c: int = (5).m(5); 16 | } 17 | -------------------------------------------------------------------------------- /test/sema/positive/methods8.impala: -------------------------------------------------------------------------------- 1 | trait T[A] { 2 | fn m(Self, A) -> A; 3 | } 4 | 5 | fn main[B:T[int]+T[bool]](b: B) -> () { 6 | let c: bool = b.m(true); 7 | let d: int = b.m(5); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/mutual_recursion1.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | g() 3 | } 4 | fn g() -> () { 5 | f() 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/mutual_recursion2.impala: -------------------------------------------------------------------------------- 1 | fn even(x : i32) -> bool { 2 | if (x == 0) { 3 | true 4 | } else { 5 | odd(x-1) 6 | } 7 | } 8 | 9 | fn odd(x : i32) -> bool { 10 | if (x == 0) { 11 | false 12 | } else { 13 | even(x-1) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sema/positive/nested_lambdas.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | |x||y, z| x + y + z; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/noret.impala: -------------------------------------------------------------------------------- 1 | fn main(f: fn() -> !) -> ! { 2 | f() 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/not.impala: -------------------------------------------------------------------------------- 1 | fn main(i : int) -> int { 2 | if !!!(i == !i) { 3 | 23 4 | } else { 5 | 42 6 | } 7 | } 8 | 9 | extern fn foo(i: bool) -> int { 10 | if i == false { 11 | 23 12 | } else { 13 | 42 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sema/positive/ptr.impala: -------------------------------------------------------------------------------- 1 | fn main() -> ~int { 2 | let p = ~~42; 3 | *p 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/range.impala: -------------------------------------------------------------------------------- 1 | trait Iterator { 2 | fn inc(self: Self) -> Self; 3 | fn lt(self: Self, other: Self) -> bool; 4 | } 5 | 6 | impl Iterator for i32 { 7 | fn inc(self: i32) -> i32 { self + 1 } 8 | fn lt(self: i32, other: i32) -> bool { self < other } 9 | } 10 | 11 | fn range[I: Iterator](a: I, b: I, body: fn(I)->()) -> () { 12 | if (a.lt(b)) { 13 | body(a); 14 | range[I](a.inc(), b, body) 15 | } else { 16 | return() 17 | } 18 | } 19 | 20 | fn main() -> () { 21 | range[i32](0, 10, |i:i32|->() {}); 22 | } 23 | -------------------------------------------------------------------------------- /test/sema/positive/repeated_definite_array_expr01.impala: -------------------------------------------------------------------------------- 1 | fn main() -> int { 2 | let x: [int*2] = [0, ..2]; 3 | x(0) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/repeated_definite_array_expr02.impala: -------------------------------------------------------------------------------- 1 | fn main() -> int { 2 | let x: [int*2] = [0, ..2i16]; 3 | x(0) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/return1.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | } 3 | -------------------------------------------------------------------------------- /test/sema/positive/return2.impala: -------------------------------------------------------------------------------- 1 | fn f() -> i32 { 2 | 1 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/return3.impala: -------------------------------------------------------------------------------- 1 | fn f(g : fn() -> (int, int)) -> (int, int) { 2 | g() 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/return4.impala: -------------------------------------------------------------------------------- 1 | fn f() -> i32 { 2 | return(4) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/return5.impala: -------------------------------------------------------------------------------- 1 | fn f() -> (i32, bool) { 2 | return(2, true) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/return6.impala: -------------------------------------------------------------------------------- 1 | fn iid(i: int) -> int { 2 | i 3 | } 4 | 5 | fn main() -> () { 6 | let x: int = iid(5); 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/retvoid.impala: -------------------------------------------------------------------------------- 1 | fn main(i : int) -> () {} 2 | -------------------------------------------------------------------------------- /test/sema/positive/scoping1.impala: -------------------------------------------------------------------------------- 1 | fn fun(f: fn[A](A)->A, g: fn[A](A)->A) -> () {} 2 | -------------------------------------------------------------------------------- /test/sema/positive/simd.impala: -------------------------------------------------------------------------------- 1 | fn simd_type(id: int) -> float { 2 | let i = simd[1.0f, 2.0f, 3.0f, 4.0f]; 3 | let j = simd[2.0f, 4.0f, 5.0f, 1.0f]; 4 | let k = i + j * simd[2.0f, 2.0f, 2.0f, 2.0f]; 5 | let l = simd[1, 2, 3, 4]; 6 | 7 | let m = !(j < k); 8 | 9 | if m(id) { 10 | k(id) + i(l(id)) 11 | } else { 12 | i(id) * k(2) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sema/positive/struct01.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | } 3 | 4 | fn f() -> S { 5 | S {} 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/struct02.impala: -------------------------------------------------------------------------------- 1 | struct A { 2 | x: int 3 | } 4 | 5 | struct B { 6 | x: int, 7 | } 8 | 9 | struct C { 10 | x: int, 11 | y: float 12 | } 13 | 14 | struct D { 15 | x: int, 16 | y: float, 17 | } 18 | 19 | fn f() -> A { 20 | A{ x: 5 } 21 | } 22 | -------------------------------------------------------------------------------- /test/sema/positive/struct03.impala: -------------------------------------------------------------------------------- 1 | struct S { 2 | x: int, 3 | y: bool 4 | } 5 | 6 | fn foo() -> S { 7 | let mut s = S { x: 5, y: true }; 8 | s.x = 6; 9 | s.y = false; 10 | s 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/positive/struct04.impala: -------------------------------------------------------------------------------- 1 | struct S[A] { 2 | x: A 3 | } 4 | 5 | fn f() -> S[int] { 6 | S[int] { x: 5 } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/struct05.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | impl T for int {} 3 | 4 | struct S[A:T] { 5 | x: A 6 | } 7 | 8 | fn f() -> S[int] { 9 | S[int] { x: 5 } 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/struct_lambda01.impala: -------------------------------------------------------------------------------- 1 | struct B { 2 | x : V 3 | } 4 | struct V {} 5 | type Fn = fn(fn(B) -> ()) -> (); 6 | fn foo(f : Fn) -> () { 7 | f(|b| -> () {}) 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test/sema/positive/struct_lambda02.impala: -------------------------------------------------------------------------------- 1 | 2 | type IterateTrianglesFn = fn (i32, fn (Tri) -> ()) -> (); 3 | 4 | struct Tri { 5 | v0: fn () -> i32 6 | } 7 | 8 | fn iterate_triangles() -> IterateTrianglesFn { 9 | |id, body| { } 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/struct_typedef01.impala: -------------------------------------------------------------------------------- 1 | struct S { x: int } 2 | 3 | type T = S; 4 | 5 | fn main() -> int { 6 | let s: T = T { x: 4 }; 7 | s.x 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/struct_typedef02.impala: -------------------------------------------------------------------------------- 1 | struct S[X] { x: X } 2 | 3 | type T[Y] = S[Y]; 4 | 5 | fn main() -> int { 6 | let s: T[int] = T[int] { x: 4 }; 7 | s.x 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping1.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | impl T for int {} 3 | fn fun1[A](a: A) -> A { 4 | a 5 | } 6 | fn fun2(f: fn[A:T](A)->A) -> int { 7 | f[int](0) 8 | } 9 | fn main() -> () { 10 | fun2(fun1); 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping2_ptr.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x : int = 5; 3 | let y : &int = ~x; 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping3_array.impala: -------------------------------------------------------------------------------- 1 | fn main(x: [int * 2]) -> () { 2 | let y : [int] = x; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping3_rec.impala: -------------------------------------------------------------------------------- 1 | fn main(x: ([int*2], int)) -> () { 2 | let y : ([int], int) = x; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping4.impala: -------------------------------------------------------------------------------- 1 | fn main(x: fn[A]([int*2], A)) -> () { 2 | let y : fn[A]([int], A) = x; 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping5.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U: T {} 3 | 4 | fn main(x: fn[A: T]([int*2], A)) -> () { 5 | let y : fn[A: U]([int], A) = x; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping6_rec.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x : int = 5; 3 | let mut y : ~int = ~x; 4 | let z : &~int = &y; 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping_traits1.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U : T {} 3 | 4 | impl T for i32 {} 5 | impl U for i32 {} 6 | 7 | fn f[A: T](a: A) -> A { a } 8 | 9 | fn g() -> i32 { 10 | f[i32](4) 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/positive/subtyping_traits2.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U : T {} 3 | 4 | fn f[C: T](c: C) -> C { c } 5 | 6 | fn g[D: U](d: D) -> D { 7 | f[D](d) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/super_traits1.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U : T {} 3 | trait V : T {} 4 | trait W : U, V {} 5 | -------------------------------------------------------------------------------- /test/sema/positive/super_traits2.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> Self; 3 | } 4 | trait U : T {} 5 | 6 | impl U for i32 { 7 | fn f(self: i32) -> i32 { self } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/super_traits3.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f(self: Self) -> Self; 3 | } 4 | trait U : T {} 5 | trait V : T { 6 | fn g(self: Self) -> i32; 7 | } 8 | trait W : U, V {} 9 | 10 | impl W for i32 { 11 | fn f(self: i32) -> i32 { self } 12 | fn g(self: i32) -> i32 { self } 13 | } 14 | -------------------------------------------------------------------------------- /test/sema/positive/super_traits4.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn to_i(self: Self) -> i32; 3 | } 4 | trait U : T { 5 | fn to_b(self: Self) -> bool; 6 | } 7 | 8 | fn h[A: U](a: A) -> i32 { 9 | if (a.to_b()) { 10 | a.to_i() 11 | } else { 12 | 0 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sema/positive/super_traits5.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn f(self: Self) -> B; 3 | } 4 | trait U[D] : T[D] {} 5 | 6 | impl U[i32] for bool { 7 | fn f(self: bool) -> i32 { 8 | if (self) { 1 } else { 0 } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/super_traits6.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn conv(self: Self) -> B; 3 | } 4 | trait U[D] : T[D] {} 5 | 6 | fn g[E, F: U[E]](f: F) -> E { 7 | f.conv() 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/trait_def_after_usage.impala: -------------------------------------------------------------------------------- 1 | fn myf[A:T](x : A) -> A { 2 | x 3 | } 4 | trait T {} 5 | -------------------------------------------------------------------------------- /test/sema/positive/trait_impls1.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U : T {} 3 | 4 | impl U for i32 {} 5 | impl T for i32 {} 6 | -------------------------------------------------------------------------------- /test/sema/positive/trait_impls2.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U : T {} 3 | 4 | impl T for i32 {} 5 | impl U for i32 {} 6 | -------------------------------------------------------------------------------- /test/sema/positive/tuples01.impala: -------------------------------------------------------------------------------- 1 | fn f(x:(int,int)) -> (int,int) { 2 | x 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/tuples02.impala: -------------------------------------------------------------------------------- 1 | fn f() -> (int, int) { 2 | (1, 2) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/tuples03.impala: -------------------------------------------------------------------------------- 1 | fn main() -> int { 2 | let x: (int, int) = (1,2); 3 | x(0) + x(1) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/typedef.impala: -------------------------------------------------------------------------------- 1 | type i = i32; 2 | type F[X, Y] = (X, Y); 3 | type Fi[Y] = F[i, Y]; 4 | 5 | fn main(a: Fi[bool]) -> (i32, bool) { 6 | a 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/typedef_struct.impala: -------------------------------------------------------------------------------- 1 | type T = S; 2 | 3 | struct S { 4 | i: int, 5 | f: float, 6 | } 7 | 8 | struct U { 9 | t: T, 10 | } 11 | 12 | struct V[T] { 13 | a: [T * 3], 14 | } 15 | 16 | type Vint = V[int]; 17 | 18 | extern fn f(t: T) -> S { 19 | U{t: t}; 20 | U{t: S{i: 23, f: 42.f}}; 21 | Vint{a: [1, 2, 3]}; 22 | T[]{i: 23, f: 42.f} 23 | } 24 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation1.impala: -------------------------------------------------------------------------------- 1 | fn myf(x: int, f: fn[A](A)->bool) -> bool { 2 | f[int](x) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation10.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | trait U {} 3 | 4 | fn f[C: T](c: C) -> C { c } 5 | 6 | fn g[D: U+T](d: D) -> D { 7 | f[D](d) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation11.impala: -------------------------------------------------------------------------------- 1 | trait T { 2 | fn f[B](self: Self, b: B) -> B; 3 | } 4 | 5 | fn g[C: T](c: C) -> i32 { 6 | c.f[i32](52) 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation12.impala: -------------------------------------------------------------------------------- 1 | trait U {} 2 | 3 | struct S[A] { x: A } 4 | 5 | impl[B] U for S[B] {} 6 | fn g[C: U](x: C) -> () {} 7 | 8 | fn main() -> () { 9 | g[S[int]](S { x: 5 }) 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation2.impala: -------------------------------------------------------------------------------- 1 | fn myf[A](x: A, f: fn[B](B)->B) -> A { 2 | f[A](x) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation3.impala: -------------------------------------------------------------------------------- 1 | fn myf(x: int, f:fn[A](A)->A, g: fn[A](A, fn[B](B)->B)->A) -> int { 2 | g[int](x, f) 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation4.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | fn myf(x: int, f:fn[A:T[int]](A)->A, g: fn[A](A, fn[B:T[A]](B)->B)->A) -> int { 3 | g[int](x, f) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation5.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | fn myf[A:T](x: A, f: fn[B:T](B)->B) -> A { 3 | f[A](x) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation6.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | impl T for int {} 3 | fn myf(x: int, f: fn[B:T](B)->B) -> int { 4 | f[int](x) 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation7.impala: -------------------------------------------------------------------------------- 1 | trait T[A] {} 2 | fn myf[B, C:T[B]](x: C, f: fn[D:T[B]](D)->D) -> C { 3 | f[C](x) 4 | } 5 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation8.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | impl[A] T[A] for i32 {} 3 | fn f[A : T[bool]](x:A) -> A { 4 | x 5 | } 6 | fn main() -> i32 { 7 | f[i32](4) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation9.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | impl[A] T[A] for i32 {} 3 | fn g[B:T[A], A](x:B) -> B { 4 | x 5 | } 6 | fn main() -> i32 { 7 | g[i32, bool](4) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation_with_subtyping.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | trait U[Y] : T[Y] {} 3 | impl[A] T[A] for i32 {} 4 | impl[B] U[B] for i32 {} 5 | fn f[A : T[bool]](x:A) -> A { 6 | x 7 | } 8 | fn main() -> i32 { 9 | f[i32](42) 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/typevar_instantiation_with_subtyping2.impala: -------------------------------------------------------------------------------- 1 | trait T[A, B] {} 2 | trait U[C, D, E] : T[int, E] {} 3 | impl[F] T[F, bool] for int {} 4 | impl[G] U[f32, G, G] for int {} 5 | fn f[G : T[int, bool]](x:G) -> G { 6 | x 7 | } 8 | fn main() -> () { 9 | f[i32](42); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/positive/unary_minus.impala: -------------------------------------------------------------------------------- 1 | fn main(i : int) -> int { 2 | -1 + i 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/negative/map1.impala: -------------------------------------------------------------------------------- 1 | struct ListElem[A] { 2 | val: A, 3 | next: ~ListElem[A] 4 | } 5 | 6 | fn map[B, C](f: fn(B)->C, l: &ListElem[B]) -> &ListElem[C] { 7 | if (l == null) { 8 | null 9 | } else { 10 | ListElem[C] { val: f(l.val), next: map(f, l.next) } 11 | } 12 | } 13 | 14 | fn main() -> () { 15 | map(|x| x, null); 16 | } 17 | -------------------------------------------------------------------------------- /test/type_inference/negative/map1.output: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/type_inference/negative/map1.output -------------------------------------------------------------------------------- /test/type_inference/negative/map2.impala: -------------------------------------------------------------------------------- 1 | struct ListElem[A] { 2 | val: A, 3 | next: ~ListElem[A] 4 | } 5 | 6 | fn map[B, C](f: fn(B)->C, l: &ListElem[B]) -> &ListElem[C] { 7 | if (l == null) { 8 | null 9 | } else { 10 | ListElem[C] { val: f(l.val), next: map(f, l.next) } 11 | } 12 | } 13 | 14 | fn main() -> &ListElem[i32] { 15 | // here we do not know the first type argument B of map 16 | map(|x| x, null) 17 | } 18 | -------------------------------------------------------------------------------- /test/type_inference/negative/map2.output: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyDSL/impala/a98cb0c48f1e499b742630a963226962799b1927/test/type_inference/negative/map2.output -------------------------------------------------------------------------------- /test/type_inference/negative/subtype_fnargs1.impala: -------------------------------------------------------------------------------- 1 | extern 2 | fn foo() -> () { 3 | let bar = |i: &mut int| { *i = 42; }; 4 | foobar(bar) 5 | } 6 | fn foobar(fun: fn(&int) -> ()) -> () { fun(45); fun(45); fun(55) } 7 | -------------------------------------------------------------------------------- /test/type_inference/negative/subtype_fnargs1.output: -------------------------------------------------------------------------------- 1 | subtype_fnargs1.impala:4 col 12 - 14: error: mismatched types: expected 'fn(&i32) -> ()' but found 'fn(&mut i32) -> ()' as argument type 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args1.impala: -------------------------------------------------------------------------------- 1 | fn f[A](g: fn(fn(A)->A)->(), a: A) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | f(|x: fn(i32)->i32| -> () {}, true) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args1.output: -------------------------------------------------------------------------------- 1 | type_args1.impala:5 col 35 - 38: error: mismatched types: expected 'i32' but found 'bool' as argument type 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args10.impala: -------------------------------------------------------------------------------- 1 | // if we do the fixed-point iteration we must be very careful 2 | // to recheck everything in the end: 3 | 4 | trait T {} 5 | fn f[X: T](x: X) -> () {} 6 | 7 | fn range1[A](n: A, f: fn(A) -> ()) -> () {} 8 | fn range2[A](f: fn(A) -> (), n: A) -> () {} 9 | 10 | fn main[B](b: B) -> () { 11 | range1(b, |x| { f(x) }); 12 | range2(|x| { f(x) }, b); 13 | } 14 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args10.output: -------------------------------------------------------------------------------- 1 | TODO when fixed-point iteration is implemented 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args2.impala: -------------------------------------------------------------------------------- 1 | fn f[A](g: fn(fn(A)->A)->(), a: A) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | f(|x: fn(bool)->i32| -> () {}, true) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args2.output: -------------------------------------------------------------------------------- 1 | type_args2.impala:5 col 8 - 23: error: could not infer types: expected 'fn(bool) -> bool' but found 'fn(bool) -> i32' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args3.impala: -------------------------------------------------------------------------------- 1 | fn f[A](a: A, g: fn(fn(A)->A)->()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | f(true, |x: fn(i32)->i32| -> () {}) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args3.output: -------------------------------------------------------------------------------- 1 | type_args3.impala:5 col 14 - 28: error: could not infer types: expected 'fn(bool) -> bool' but found 'fn(i32) -> i32' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args4.impala: -------------------------------------------------------------------------------- 1 | trait T {} 2 | 3 | fn f[A: T](a: A) -> A { a } 4 | 5 | fn main() -> () { 6 | f(5); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args4.output: -------------------------------------------------------------------------------- 1 | type_args4.impala:6 col 5 - 8: error: 'i32' (instance for 'A') does not implement bound 'T' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args5.impala: -------------------------------------------------------------------------------- 1 | fn f[A](a: fn() -> (), g: fn[B](B, A) -> B) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | f(|| {}, |b, a| { b }); 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args5.output: -------------------------------------------------------------------------------- 1 | type_args5.impala:5 col 5 - 26: error: could not find instance for type variable 'A' of function 'f' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args6.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | impl T[bool] for i32 {} 3 | impl T[i32] for i32 {} 4 | 5 | fn f[A, B: T[A]](b: B) -> () {} 6 | 7 | fn main() -> () { 8 | f(4) 9 | } 10 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args6.output: -------------------------------------------------------------------------------- 1 | type_args6.impala:8 col 5 - 8: error: could not find instance for type variable 'A' of function 'f' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args7.impala: -------------------------------------------------------------------------------- 1 | fn main(f: fn[A,B]()->B) -> () { 2 | let x:int = f(); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args7.output: -------------------------------------------------------------------------------- 1 | type_args7.impala:2 col 17 - 19: error: could not find instance for type variable 'A' of function 'f' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args8.impala: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | f(|y| y); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args8.output: -------------------------------------------------------------------------------- 1 | type_args8.impala:6 col 8: error: could not infer parameter type for y 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args9.impala: -------------------------------------------------------------------------------- 1 | fn f[T](g: fn(T)->T) -> () {} 2 | 3 | fn main() -> () { 4 | f(|x| x); 5 | } 6 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_args9.output: -------------------------------------------------------------------------------- 1 | type_args9.impala:4 col 5 - 12: error: could not find instance for type variable 'T' of function 'f' 2 | -------------------------------------------------------------------------------- /test/type_inference/negative/type_struct.impala: -------------------------------------------------------------------------------- 1 | struct A[T] { 2 | data : &[T] 3 | } 4 | 5 | fn test() -> () { 6 | let tmp = A { data : ~[23:float] }; 7 | } 8 | 9 | fn testt[T]() -> () { 10 | let foo = A { data : ~[23:T] }; 11 | let bar = A[T] { data : ~[23:float] }; // what happens if T != float? 12 | } 13 | -------------------------------------------------------------------------------- /test/type_inference/negative/unused_typevar1.impala: -------------------------------------------------------------------------------- 1 | fn f[A](g: fn(A) -> A) -> i32 { 2 | 4 3 | } 4 | 5 | fn main() -> () { 6 | f(|x| x); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/negative/unused_typevar1.output: -------------------------------------------------------------------------------- 1 | unused_typevar1.impala:6 col 5 - 12: error: could not find instance for type variable 'A' of function 'f' 2 | -------------------------------------------------------------------------------- /test/type_inference/positive/bottom_up1.impala: -------------------------------------------------------------------------------- 1 | fn main(f: fn[X](fn()->X)->X) -> () { 2 | f(|| 4); 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/bottom_up1.output: -------------------------------------------------------------------------------- 1 | fn main(f: fn[X](fn() -> X) -> X) -> () { 2 | (f[i32](|| -> i32 4)); 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/fixed_point_iteration01.impala: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> () {} 2 | 3 | fn range1[A](n: A, f: fn(A) -> ()) -> () {} 4 | fn range2[A](f: fn(A) -> (), n: A) -> () {} 5 | 6 | fn main() -> () { 7 | range1(4, |x| { f(x) }); 8 | range2(|x| { f(x) }, 4); 9 | } 10 | -------------------------------------------------------------------------------- /test/type_inference/positive/fixed_point_iteration01.output: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> () { 2 | } 3 | 4 | fn range1[A](n: A, f: fn(A) -> ()) -> () { 5 | } 6 | 7 | fn range2[A](f: fn(A) -> (), n: A) -> () { 8 | } 9 | 10 | fn main() -> () { 11 | range1[i32](4, |x: i32| -> () { 12 | f[i32](x) 13 | }); 14 | range2[i32](|x: i32| -> () { 15 | f[i32](x) 16 | }, 4); 17 | } 18 | -------------------------------------------------------------------------------- /test/type_inference/positive/hard1.impala: -------------------------------------------------------------------------------- 1 | fn f[A](a: fn() -> A, g: fn[B](B, A) -> B) -> i32 { 2 | g(4, a()) 3 | } 4 | 5 | fn main() -> () { 6 | f(|| { true }, |b, a| { b }); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/hard1.output: -------------------------------------------------------------------------------- 1 | fn f[A](a: fn() -> A, g: fn[B](B, A) -> B) -> i32 { 2 | (g[i32](4, (a()))) 3 | } 4 | 5 | fn main() -> () { 6 | (f[bool](|| -> bool { 7 | true 8 | }, |b: _39_, a: bool| -> _39_ { 9 | b 10 | })); 11 | } 12 | -------------------------------------------------------------------------------- /test/type_inference/positive/hard2.impala: -------------------------------------------------------------------------------- 1 | trait T[B] { 2 | fn conv(self: Self) -> B; 3 | } 4 | 5 | // implementation is possible! 6 | struct S[C] { 7 | val: C 8 | } 9 | impl[D] T[D] for S[D] { 10 | fn conv(self: S[D]) -> D { self.val } 11 | } 12 | 13 | // problems for type inference 14 | fn g[E, F: T[E]](f: F) -> E { 15 | f.conv() 16 | } 17 | 18 | fn main() -> bool { 19 | let x = S[bool]{ val: true }; 20 | g(x) 21 | } 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /test/type_inference/positive/hard3.impala: -------------------------------------------------------------------------------- 1 | fn b1[A](a: A) -> bool { true } 2 | fn b2[A](a: A) -> bool { false } 3 | 4 | fn main() -> bool { 5 | b1(b2(5)) 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/hard3.output: -------------------------------------------------------------------------------- 1 | fn b1[A](a: A) -> bool { 2 | true 3 | } 4 | 5 | fn b2[A](a: A) -> bool { 6 | false 7 | } 8 | 9 | fn main() -> bool { 10 | (b1[bool]((b2[i32](5)))) 11 | } 12 | -------------------------------------------------------------------------------- /test/type_inference/positive/id_id.impala: -------------------------------------------------------------------------------- 1 | fn id[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | id(id); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/id_id.output: -------------------------------------------------------------------------------- 1 | fn id[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | (id[fn[X](X) -> X](id)); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/id_twice.impala: -------------------------------------------------------------------------------- 1 | fn main() -> i32 { 2 | let id = |x| x; 3 | id(1i32) + id(1i32) 4 | } 5 | -------------------------------------------------------------------------------- /test/type_inference/positive/id_twice.output: -------------------------------------------------------------------------------- 1 | fn main() -> i32 { 2 | let id: fn(i32, fn(i32)) = |x: i32| -> i32 x; 3 | ((id(1)) + (id(1))) 4 | } 5 | -------------------------------------------------------------------------------- /test/type_inference/positive/if01.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: fn(int) -> int = if (true) { 3 | |a| a 4 | } else { 5 | |a| a+1 6 | }; 7 | } -------------------------------------------------------------------------------- /test/type_inference/positive/if01.output: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: fn(i32) -> i32 = if true { 3 | |a: i32| -> i32 a 4 | } else { 5 | |a: i32| -> i32 (a + 1) 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/if02.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: fn(int) -> int = if (true) { 3 | return() 4 | } else { 5 | |a| a+1 6 | }; 7 | } -------------------------------------------------------------------------------- /test/type_inference/positive/if02.output: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: fn(i32) -> i32 = if true { 3 | (return()) 4 | } else { 5 | |a: i32| -> i32 (a + 1) 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/if03.impala: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: fn(int) -> int = if (true) { 3 | |a| a 4 | } else { 5 | return() 6 | }; 7 | } -------------------------------------------------------------------------------- /test/type_inference/positive/if03.output: -------------------------------------------------------------------------------- 1 | fn f() -> () { 2 | let x: fn(i32) -> i32 = if true { 3 | |a: i32| -> i32 a 4 | } else { 5 | (return()) 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/let1.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x = 4; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /test/type_inference/positive/let1.output: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x: i32 = 4; 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/map.impala: -------------------------------------------------------------------------------- 1 | struct ListElem[A] { 2 | val: A, 3 | next: ~ListElem[A] 4 | } 5 | 6 | fn map[B, C](f: fn(B)->C, l: &ListElem[B]) -> &ListElem[C] { 7 | if (l == null) { 8 | null 9 | } else { 10 | ListElem[C] { val: f(l.val), next: map(f, l.next) } 11 | } 12 | } 13 | 14 | fn main() -> &ListElem[i32] { 15 | let l1: ListElem[i32] = ListElem[i32] { val: 2, next: null }; 16 | let l2: ListElem[i32] = ListElem[i32] { val: 2, next: l1 }; 17 | map(|x| x+1, l2) 18 | } 19 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference1.impala: -------------------------------------------------------------------------------- 1 | fn f(g: fn(i32)->i32) -> i32 { 2 | g(5) 3 | } 4 | 5 | fn main() -> i32 { 6 | f(|x| -> i32 x+1) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference1.output: -------------------------------------------------------------------------------- 1 | fn f(g: fn(i32) -> i32) -> i32 { 2 | (g(5)) 3 | } 4 | 5 | fn main() -> i32 { 6 | (f(|x: i32| -> i32 (x + 1))) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference2.impala: -------------------------------------------------------------------------------- 1 | fn f(g: fn(i32)->i32) -> i32 { 2 | g(5) 3 | } 4 | 5 | fn main() -> i32 { 6 | f(|x| x+1) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference2.output: -------------------------------------------------------------------------------- 1 | fn f(g: fn(i32) -> i32) -> i32 { 2 | (g(5)) 3 | } 4 | 5 | fn main() -> i32 { 6 | (f(|x: i32| -> i32 (x + 1))) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference3.impala: -------------------------------------------------------------------------------- 1 | fn f(g: fn[A](A)->A) -> i32 { 2 | g(5) 3 | } 4 | 5 | fn main() -> i32 { 6 | f(|x| x) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference3.output: -------------------------------------------------------------------------------- 1 | fn f(g: fn[A](A) -> A) -> i32 { 2 | (g[i32](5)) 3 | } 4 | 5 | fn main() -> i32 { 6 | (f(|x: _28_| -> _28_ x)) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference4.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x:fn(int)->int = |p| p; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /test/type_inference/positive/param_inference4.output: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let x: fn(i32) -> i32 = |p: i32| -> i32 p; 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/poly_pass1.impala: -------------------------------------------------------------------------------- 1 | fn id[A](a: A) -> A { a } 2 | 3 | fn f(g: fn(i32)->i32) -> i32 { 4 | g(4) 5 | } 6 | 7 | fn main() -> i32 { 8 | f(id) 9 | } 10 | -------------------------------------------------------------------------------- /test/type_inference/positive/range.impala: -------------------------------------------------------------------------------- 1 | trait Iterator { 2 | fn inc(self: Self) -> Self; 3 | fn lt(self: Self, other: Self) -> bool; 4 | } 5 | 6 | impl Iterator for i32 { 7 | fn inc(self: i32) -> i32 { self + 1 } 8 | fn lt(self: i32, other: i32) -> bool { self < other } 9 | } 10 | 11 | fn range[I: Iterator](a: I, b: I, body: fn(I)->()) -> () { 12 | if (a.lt(b)) { 13 | body(a); 14 | range(a.inc(), b, body) 15 | } else { 16 | return() 17 | } 18 | } 19 | 20 | fn main() -> () { 21 | range(0, 10, |i| {}); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /test/type_inference/positive/range.output: -------------------------------------------------------------------------------- 1 | trait Iterator { 2 | fn inc(self: Self) -> Self; 3 | fn lt(self: Self, other: Self) -> bool; 4 | } 5 | 6 | impl Iterator for i32 { 7 | fn inc(self: i32) -> i32 { 8 | (self + 1) 9 | } 10 | fn lt(self: i32, other: i32) -> bool { 11 | (self < other) 12 | } 13 | } 14 | 15 | fn range[I: Iterator](a: I, b: I, body: fn(I) -> ()) -> () { 16 | if ((a.lt)(b)) { 17 | (body(a)); 18 | (range[I](((a.inc)()), b, body)) 19 | } else { 20 | (return()) 21 | } 22 | } 23 | 24 | fn main() -> () { 25 | (range[i32](0, 10, |i: i32| -> () { 26 | })); 27 | } 28 | -------------------------------------------------------------------------------- /test/type_inference/positive/ret_lambda.impala: -------------------------------------------------------------------------------- 1 | fn f() -> fn(int, int) -> int { 2 | |x, y| x+y 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/return_lambda.impala: -------------------------------------------------------------------------------- 1 | fn f(a: int) -> fn(int) -> int { 2 | |i| if i == a { i + a } else { i + 42 } 3 | } 4 | 5 | fn main(i: int) -> int { 6 | f(i)(i) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/return_lambda.output: -------------------------------------------------------------------------------- 1 | fn f(a: i32) -> fn(i32) -> i32 { 2 | |i: i32| -> i32 if (i == a) { 3 | (i + a) 4 | } else { 5 | (i + 42) 6 | } 7 | } 8 | 9 | fn main(i: i32) -> i32 { 10 | ((f(i))(i)) 11 | } 12 | -------------------------------------------------------------------------------- /test/type_inference/positive/struct_ptr.impala: -------------------------------------------------------------------------------- 1 | struct S[T] { 2 | t: T 3 | } 4 | 5 | fn main() -> () { 6 | let s = S{ t: ~42 }; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/struct_ptr.output: -------------------------------------------------------------------------------- 1 | struct S[T] { 2 | t: T 3 | } 4 | 5 | fn main() -> () { 6 | let s: S[~i32] = S[~i32]{t: (~42)}; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/struct_typedef01.impala: -------------------------------------------------------------------------------- 1 | struct S { x: int } 2 | 3 | type T = S; 4 | 5 | fn main() -> int { 6 | let s: T = T { x: 4 }; 7 | let t = T { x: 4 }; 8 | s.x 9 | } 10 | -------------------------------------------------------------------------------- /test/type_inference/positive/struct_typedef01.output: -------------------------------------------------------------------------------- 1 | struct S { 2 | x: i32 3 | } 4 | 5 | type T = S; 6 | 7 | fn main() -> i32 { 8 | let s: S = T{x: 4}; 9 | let t: S = T{x: 4}; 10 | (s.x) 11 | } 12 | -------------------------------------------------------------------------------- /test/type_inference/positive/struct_typedef02.impala: -------------------------------------------------------------------------------- 1 | struct S[X] { x: X } 2 | 3 | type T[Y] = S[Y]; 4 | 5 | fn main() -> int { 6 | let s: T[int] = T { x: 4 }; 7 | let t = T { x: 4 }; 8 | s.x 9 | } 10 | -------------------------------------------------------------------------------- /test/type_inference/positive/struct_typedef02.output: -------------------------------------------------------------------------------- 1 | struct S[X] { 2 | x: X 3 | } 4 | 5 | type T[Y] = S[Y]; 6 | 7 | fn main() -> i32 { 8 | let s: S[i32] = T[i32]{x: 4}; 9 | let t: S[i32] = T[i32]{x: 4}; 10 | (s.x) 11 | } 12 | -------------------------------------------------------------------------------- /test/type_inference/positive/structs01.impala: -------------------------------------------------------------------------------- 1 | struct S[A] { x: A } 2 | fn g[B](x: B) -> () {} 3 | 4 | fn main() -> () { 5 | g(S { x: 5 }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/structs01.output: -------------------------------------------------------------------------------- 1 | struct S[A] { 2 | x: A 3 | } 4 | 5 | fn g[B](x: B) -> () { 6 | } 7 | 8 | fn main() -> () { 9 | (g[S[i32]](S[i32]{x: 5})) 10 | } 11 | -------------------------------------------------------------------------------- /test/type_inference/positive/structs02.impala: -------------------------------------------------------------------------------- 1 | struct S[X] { x: X } 2 | 3 | fn main() -> () { 4 | let s = S[fn(int)->int] { x: |a| a }; 5 | } 6 | -------------------------------------------------------------------------------- /test/type_inference/positive/structs02.output: -------------------------------------------------------------------------------- 1 | struct S[X] { 2 | x: X 3 | } 4 | 5 | fn main() -> () { 6 | let s: S[fn(i32) -> i32] = S[fn(i32) -> i32]{x: |a: i32| -> i32 a}; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/structs03.impala: -------------------------------------------------------------------------------- 1 | struct S[X] { x: X } 2 | 3 | fn main() -> () { 4 | let s : S[fn(int)->int] = S { x: |a| a }; 5 | } 6 | -------------------------------------------------------------------------------- /test/type_inference/positive/structs03.output: -------------------------------------------------------------------------------- 1 | struct S[X] { 2 | x: X 3 | } 4 | 5 | fn main() -> () { 6 | let s: S[fn(i32) -> i32] = S[fn(i32) -> i32]{x: |a: i32| -> i32 a}; 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/subtyping_if1.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let mut x = 5; 3 | let y = if true { 4 | ~x 5 | } else { 6 | &x 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/subtyping_if1.output: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let mut x: i32 = 5; 3 | let y: &i32 = if true { 4 | (~x) 5 | } else { 6 | (&x) 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/subtyping_if2.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let mut x = 5; 3 | let y = if true { 4 | &x 5 | } else { 6 | ~x 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/subtyping_if2.output: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let mut x: i32 = 5; 3 | let y: &i32 = if true { 4 | (&x) 5 | } else { 6 | (~x) 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args1.impala: -------------------------------------------------------------------------------- 1 | fn id[A](a: A) -> A { 2 | a 3 | } 4 | fn main() -> i32 { 5 | id(4) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args1.output: -------------------------------------------------------------------------------- 1 | fn id[A](a: A) -> A { 2 | a 3 | } 4 | 5 | fn main() -> i32 { 6 | (id[i32](4)) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args10.impala: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | f(|y| y+1); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args10.ouptut: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | f[i32](|y: i32| -> i32 y+1); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args11.impala: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | f(|y: int| y); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args11.output: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | f[i32](|y: i32| -> i32 y); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args12.impala: -------------------------------------------------------------------------------- 1 | fn f[X](i: int, x: X) -> X { 2 | x 3 | } 4 | 5 | fn g[Y](h: fn[Z](Y, Z) -> Z) -> () { 6 | } 7 | 8 | fn main() -> () { 9 | g(f); 10 | } 11 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args12.output: -------------------------------------------------------------------------------- 1 | fn f[X](i: i32, x: X) -> X { 2 | x 3 | } 4 | 5 | fn g[Y](h: fn[Z](Y, Z) -> Z) -> () { 6 | } 7 | 8 | fn main() -> () { 9 | g[i32](f); 10 | } 11 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args13.impala: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let f = |x| -> () { let a:int = x; }; 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args13.output: -------------------------------------------------------------------------------- 1 | fn main() -> () { 2 | let f: fn(i32) -> () = |x: i32| -> () { 3 | let a: i32 = x; 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args14.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x| { 1+x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args14.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range[i32](|x: i32| -> () { 6 | (1 + x); 7 | }) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args2.impala: -------------------------------------------------------------------------------- 1 | fn f[A](g: fn(fn(A)->A)->()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | f(|x: fn(bool)->bool| -> () {}) 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args2.output: -------------------------------------------------------------------------------- 1 | fn f[A](g: fn(fn(A) -> A) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (f[bool](|x: fn(bool) -> bool| -> () { 6 | })) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args3.impala: -------------------------------------------------------------------------------- 1 | fn f[A](a: A, g: fn(fn(A)->A)->()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | f(true, |x| -> () {}) 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args3.output: -------------------------------------------------------------------------------- 1 | fn f[A](a: A, g: fn(fn(A) -> A) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (f[bool](true, |x: fn(bool) -> bool| -> () { 6 | })) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args4.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | 3 | fn f[A, B: T[A]](b: B) -> () {} 4 | 5 | fn main[C: T[bool]](c: C) -> () { 6 | f(c) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args4.output: -------------------------------------------------------------------------------- 1 | trait T[X] { 2 | 3 | } 4 | 5 | fn f[A, B: T[A]](b: B) -> () { 6 | } 7 | 8 | fn main[C: T[bool]](c: C) -> () { 9 | f[bool, C](c) 10 | } 11 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args5.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | 3 | fn f[A, B: T[A]](b: B) -> () {} 4 | 5 | fn main[C, D: T[C]](d: D) -> () { 6 | f(d) 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args5.output: -------------------------------------------------------------------------------- 1 | trait T[X] { 2 | 3 | } 4 | 5 | fn f[A, B: T[A]](b: B) -> () { 6 | } 7 | 8 | fn main[C, D: T[C]](d: D) -> () { 9 | f[C, D](d) 10 | } 11 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args6.impala: -------------------------------------------------------------------------------- 1 | trait T[X] {} 2 | impl T[bool] for i32 {} 3 | 4 | fn f[A, B: T[A]](b: B) -> () {} 5 | 6 | fn main() -> () { 7 | f(4) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args6.output: -------------------------------------------------------------------------------- 1 | trait T[X] { 2 | 3 | } 4 | 5 | impl T[bool] for i32 { 6 | 7 | } 8 | 9 | fn f[A, B: T[A]](b: B) -> () { 10 | } 11 | 12 | fn main() -> () { 13 | f[bool, i32](4) 14 | } 15 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args8.impala: -------------------------------------------------------------------------------- 1 | fn main(f: fn[A]()->A) -> () { 2 | let x:int = f(); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args8.output: -------------------------------------------------------------------------------- 1 | fn main(f: fn[A]() -> A) -> () { 2 | let x: i32 = (f[i32]()); 3 | } 4 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args9.impala: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | let g: fn[Y](Y) -> Y = f(|y| y); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args9.output: -------------------------------------------------------------------------------- 1 | fn f[X](x: X) -> X { 2 | x 3 | } 4 | 5 | fn main() -> () { 6 | let g: fn[X](X)->X = f[fn[X](X)->X](|y: X|->X y); 7 | } 8 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_infix01.impala: -------------------------------------------------------------------------------- 1 | fn range[T,U](f: fn(T, U) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x, y| { let a:int = x+y; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_infix01.output: -------------------------------------------------------------------------------- 1 | fn range[T, U](f: fn(T, U) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[i32, i32](|x: i32, y: i32| -> () { 6 | let a: i32 = (x + y); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix01.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x| { let a:~int = ~x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix01.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[i32](|x: i32| -> () { 6 | let a: ~i32 = (~x); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix02.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|mut x| { let a:&int = &x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix02.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[i32](|mut x: i32| -> () { 6 | let a: &i32 = (&x); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix03.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x| { let a:int = *x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix03.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[&i32](|x: &i32| -> () { 6 | let a: i32 = (*x); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix04.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|mut x| { let a:int = ++x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix04.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[i32](|mut x: i32| -> () { 6 | let a: i32 = (++x); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix05.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x| { let a:int = -x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix05.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[i32](|x: i32| -> () { 6 | let a: i32 = (-x); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix06.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x| { let a:int = !x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix06.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[i32](|x: i32| -> () { 6 | let a: i32 = (!x); 7 | })) 8 | } 9 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix07.impala: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | range(|x| { let a:bool = !x; }) 6 | } 7 | -------------------------------------------------------------------------------- /test/type_inference/positive/type_args_prefix07.output: -------------------------------------------------------------------------------- 1 | fn range[T](f: fn(T) -> ()) -> () { 2 | } 3 | 4 | fn main() -> () { 5 | (range[bool](|x: bool| -> () { 6 | let a: bool = (!x); 7 | })) 8 | } 9 | --------------------------------------------------------------------------------