Rewrite LLVM bindings #53
@ -1,17 +1,15 @@
|
|||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- "**"
|
- "**"
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *"
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BB_CI: 1
|
BB_CI: 1
|
||||||
|
BUILD_DEBUG: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
@ -19,7 +17,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest ]
|
os: [ ubuntu-latest ]
|
||||||
BIRTH_CMAKE_BUILD_TYPE: [ Debug, Release ]
|
BIRTH_CMAKE_BUILD_TYPE: [ Debug, Release-assertions, Release ]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -32,11 +30,7 @@ jobs:
|
|||||||
CLANGXX_PATH: clang++-19
|
CLANGXX_PATH: clang++-19
|
||||||
run: |
|
run: |
|
||||||
set -eux
|
set -eux
|
||||||
./generate.sh
|
ci/reproduce.sh
|
||||||
./build.sh
|
|
||||||
./build/bb test
|
|
||||||
mkdir -p $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/$CMAKE_BUILD_TYPE
|
|
||||||
mv ./self-hosted-bb-cache $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/$CMAKE_BUILD_TYPE/cache
|
|
||||||
release:
|
release:
|
||||||
needs: ci
|
needs: ci
|
||||||
strategy:
|
strategy:
|
||||||
@ -52,8 +46,7 @@ jobs:
|
|||||||
BB_CI: 1
|
BB_CI: 1
|
||||||
run: |
|
run: |
|
||||||
set -eux
|
set -eux
|
||||||
mkdir -p $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)
|
ci/install.sh
|
||||||
cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Release/cache/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)
|
|
||||||
- name: Release (locally)
|
- name: Release (locally)
|
||||||
if: ${{ (github.ref == 'refs/heads/main') }}
|
if: ${{ (github.ref == 'refs/heads/main') }}
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -61,8 +54,7 @@ jobs:
|
|||||||
BB_CI: 1
|
BB_CI: 1
|
||||||
run: |
|
run: |
|
||||||
set -eux
|
set -eux
|
||||||
cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler $HOME/bloat-buster-artifacts/releases/main/
|
ci/release.sh
|
||||||
|
|
||||||
- name: Release (web)
|
- name: Release (web)
|
||||||
uses: akkuman/gitea-release-action@v1
|
uses: akkuman/gitea-release-action@v1
|
||||||
if: ${{ (github.ref == 'refs/heads/main') }}
|
if: ${{ (github.ref == 'refs/heads/main') }}
|
||||||
@ -70,4 +62,6 @@ jobs:
|
|||||||
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
||||||
with:
|
with:
|
||||||
files: |-
|
files: |-
|
||||||
/home/act_runner/bloat-buster-artifacts/releases/main/compiler
|
/home/act_runner/bloat-buster-artifacts/releases/main/compiler_generic_debug
|
||||||
|
/home/act_runner/bloat-buster-artifacts/releases/main/compiler_generic
|
||||||
|
/home/act_runner/bloat-buster-artifacts/releases/main/compiler_native
|
30
.gitea/workflows/pr.yml
Normal file
30
.gitea/workflows/pr.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
env:
|
||||||
|
BB_CI: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ ubuntu-latest ]
|
||||||
|
BIRTH_CMAKE_BUILD_TYPE: [ Release-assertions, Release ]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build and test (Packaged LLVM)
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
BB_CI: 1
|
||||||
|
CMAKE_BUILD_TYPE: ${{matrix.BIRTH_CMAKE_BUILD_TYPE}}
|
||||||
|
CLANG_PATH: clang-19
|
||||||
|
CLANGXX_PATH: clang++-19
|
||||||
|
run: |
|
||||||
|
set -eux
|
||||||
|
./generate.sh
|
||||||
|
./build.sh
|
||||||
|
./build/bb test
|
@ -21,7 +21,6 @@ add_executable(bb
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_library(c_abi tests/c_abi.c)
|
add_library(c_abi tests/c_abi.c)
|
||||||
add_library(llvm_bindings src/llvm.cpp)
|
|
||||||
|
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
add_compile_definitions(
|
add_compile_definitions(
|
||||||
@ -29,25 +28,25 @@ add_compile_definitions(
|
|||||||
$<$<NOT:$<CONFIG:Debug>>:BB_DEBUG=0>
|
$<$<NOT:$<CONFIG:Debug>>:BB_DEBUG=0>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
find_library(llvm_bindings NAMES libllvm_bindings.dylib libllvm_bindings.lib libllvm_bindings.a libllvm_bindingsELF.dll.a libllvm_bindingsELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
find_library(LLD_COMMON NAMES liblldCommon.dylib lldCommon.lib lldCommon.a liblldCommon.dll.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
find_library(LLD_COMMON NAMES liblldCommon.dylib lldCommon.lib lldCommon.a liblldCommon.dll.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
find_library(LLD_ELF NAMES liblldELF.dylib lldELF.lib lldELF.a liblldELF.dll.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
find_library(LLD_ELF NAMES liblldELF.dylib lldELF.lib lldELF.a liblldELF.dll.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
# find_library(LLD_COFF NAMES liblldCOFF.dylib lldCOFF.lib lldCOFF.a liblldCOFF.dll.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
find_library(LLD_COFF NAMES liblldCOFF.dylib lldCOFF.lib lldCOFF.a liblldCOFF.dll.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
# find_library(LLD_MACHO NAMES liblldMachO.dylib lldMachO.lib lldMachO.a liblldMachO.dll.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
find_library(LLD_MACHO NAMES liblldMachO.dylib lldMachO.lib lldMachO.a liblldMachO.dll.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
# find_library(LLD_MINGW NAMES liblldMinGW.dylib lldMinGW.lib lldMinGW.a liblldMinGW.dll.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
find_library(LLD_MINGW NAMES liblldMinGW.dylib lldMinGW.lib lldMinGW.a liblldMinGW.dll.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
# find_library(LLD_WASM NAMES liblldWasm.dylib lldWasm.lib lldWasm.a liblldWasm.dll.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
find_library(LLD_WASM NAMES liblldWasm.dylib lldWasm.lib lldWasm.a liblldWasm.dll.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
|
||||||
target_link_libraries(llvm_bindings PUBLIC
|
target_link_libraries(bb PUBLIC
|
||||||
${LLVM_AVAILABLE_LIBS}
|
${LLVM_AVAILABLE_LIBS}
|
||||||
${LLD_COMMON}
|
${LLD_COMMON}
|
||||||
# ${LLD_COFF}
|
${LLD_COFF}
|
||||||
${LLD_ELF}
|
${LLD_ELF}
|
||||||
# ${LLD_MACHO}
|
${LLD_MACHO}
|
||||||
# ${LLD_MINGW}
|
${LLD_MINGW}
|
||||||
# ${LLD_WASM}
|
${LLD_WASM}
|
||||||
|
${llvm_bindings}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(bb PUBLIC llvm_bindings)
|
|
||||||
|
|
||||||
add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Werror -Wno-c99-extensions -Wno-unused-function -Wno-missing-designated-field-initializers -fno-signed-char -fwrapv -fno-strict-aliasing)
|
add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Werror -Wno-c99-extensions -Wno-unused-function -Wno-missing-designated-field-initializers -fno-signed-char -fwrapv -fno-strict-aliasing)
|
||||||
add_compile_definitions(CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}")
|
add_compile_definitions(CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}")
|
||||||
add_compile_definitions(BB_CI=${BB_CI})
|
add_compile_definitions(BB_CI=${BB_CI})
|
||||||
|
7
ci/install.sh
Executable file
7
ci/install.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
set -eux
|
||||||
|
mkdir -p $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)
|
||||||
|
if [[ -n "${BUILD_DEBUG:-}" ]]; then
|
||||||
|
cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Debug/cache/generic/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_generic_debug
|
||||||
|
fi
|
||||||
|
cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Release/cache/generic/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_generic
|
||||||
|
cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Release/cache/native/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_native
|
7
ci/release.sh
Executable file
7
ci/release.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
set -eux
|
||||||
|
mkdir -p $HOME/bloat-buster-artifacts/releases/main/
|
||||||
|
if [[ -n "${BUILD_DEBUG:-}" ]]; then
|
||||||
|
cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_generic_debug $HOME/bloat-buster-artifacts/releases/main/
|
||||||
|
fi
|
||||||
|
cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_generic $HOME/bloat-buster-artifacts/releases/main/
|
||||||
|
cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_native $HOME/bloat-buster-artifacts/releases/main/
|
10
ci/release_locally.sh
Executable file
10
ci/release_locally.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eux
|
||||||
|
if [[ -n "${BUILD_DEBUG:-}" ]]; then
|
||||||
|
export BUILD_DEBUG
|
||||||
|
CMAKE_BUILD_TYPE=Debug ci/reproduce.sh
|
||||||
|
fi
|
||||||
|
CMAKE_BUILD_TYPE=Release ci/reproduce.sh
|
||||||
|
CMAKE_BUILD_TYPE=Release-assertions ci/reproduce.sh
|
||||||
|
ci/install.sh
|
||||||
|
ci/release.sh
|
8
ci/reproduce.sh
Executable file
8
ci/reproduce.sh
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
set -eux
|
||||||
|
rm -rf bb-cache self-hosted-bb-cache || true
|
||||||
|
./generate.sh
|
||||||
|
./build.sh
|
||||||
|
./build/bb test
|
||||||
|
mkdir -p $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/$CMAKE_BUILD_TYPE
|
||||||
|
mv ./self-hosted-bb-cache $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/$CMAKE_BUILD_TYPE/cache
|
||||||
|
|
11
generate.sh
11
generate.sh
@ -1,10 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -eu
|
set -eux
|
||||||
|
|
||||||
if [[ -z "${BB_CI:-}" ]]; then
|
if [[ -z "${BB_CI:-}" ]]; then
|
||||||
|
BB_CI=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${CMAKE_BUILD_TYPE:-}" ]]; then
|
||||||
CMAKE_BUILD_TYPE=Debug
|
CMAKE_BUILD_TYPE=Debug
|
||||||
LLVM_CMAKE_BUILD_TYPE=Release
|
LLVM_CMAKE_BUILD_TYPE=Release
|
||||||
BB_CI=0
|
|
||||||
else
|
else
|
||||||
LLVM_CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE
|
LLVM_CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE
|
||||||
fi
|
fi
|
||||||
@ -36,12 +39,12 @@ esac
|
|||||||
rm -rf $BUILD_DIR
|
rm -rf $BUILD_DIR
|
||||||
mkdir $BUILD_DIR
|
mkdir $BUILD_DIR
|
||||||
cd $BUILD_DIR
|
cd $BUILD_DIR
|
||||||
LLVM_PREFIX_PATH=$HOME/dev/llvm/install/llvm_20.1.3_$BIRTH_ARCH-$BIRTH_OS-$LLVM_CMAKE_BUILD_TYPE
|
LLVM_PREFIX_PATH=$HOME/dev/llvm/install/llvm_20.1.7_$BIRTH_ARCH-$BIRTH_OS-$LLVM_CMAKE_BUILD_TYPE
|
||||||
|
|
||||||
if [[ -z "${CLANG_PATH:-}" ]]; then
|
if [[ -z "${CLANG_PATH:-}" ]]; then
|
||||||
CLANG_PATH=clang
|
CLANG_PATH=clang
|
||||||
CLANGXX_PATH=clang++
|
CLANGXX_PATH=clang++
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cmake .. -G Ninja -DCMAKE_C_COMPILER=$CLANG_PATH -DCMAKE_CXX_COMPILER=$CLANGXX_PATH -DCMAKE_LINKER_TYPE=$LINKER_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_PREFIX_PATH=$LLVM_PREFIX_PATH -DCMAKE_COLOR_DIAGNOSTICS=ON -DBB_CI=$BB_CI
|
cmake .. -G Ninja -DCMAKE_C_COMPILER=$CLANG_PATH -DCMAKE_CXX_COMPILER=$CLANGXX_PATH -DCMAKE_LINKER_TYPE=$LINKER_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE%%-*} -DCMAKE_PREFIX_PATH=$LLVM_PREFIX_PATH -DCMAKE_COLOR_DIAGNOSTICS=ON -DBB_CI=$BB_CI
|
||||||
cd ..
|
cd ..
|
||||||
|
1240
src/compiler.bbb
1240
src/compiler.bbb
File diff suppressed because it is too large
Load Diff
219
src/compiler.cpp
219
src/compiler.cpp
@ -163,22 +163,39 @@ fn String compile_file(Arena* arena, Compile options)
|
|||||||
|
|
||||||
auto is_compiler = relative_file_path.equal(string_literal("src/compiler.bbb"));
|
auto is_compiler = relative_file_path.equal(string_literal("src/compiler.bbb"));
|
||||||
|
|
||||||
String output_path_dir_parts[] = {
|
make_directory(base_cache_dir);
|
||||||
|
|
||||||
|
String cpu_dir_parts[] = {
|
||||||
string_literal(base_cache_dir),
|
string_literal(base_cache_dir),
|
||||||
is_compiler ? string_literal("/compiler/") : string_literal("/"),
|
string_literal("/"),
|
||||||
|
options.host_cpu_model ? string_literal("native") : string_literal("generic"),
|
||||||
|
};
|
||||||
|
|
||||||
|
auto cpu_dir = arena_join_string(arena, array_to_slice(cpu_dir_parts));
|
||||||
|
|
||||||
|
make_directory(cstr(cpu_dir));
|
||||||
|
|
||||||
|
auto base_dir = cpu_dir;
|
||||||
|
|
||||||
|
if (is_compiler)
|
||||||
|
{
|
||||||
|
String compiler_dir_parts[] = {
|
||||||
|
base_dir,
|
||||||
|
string_literal("/compiler"),
|
||||||
|
};
|
||||||
|
base_dir = arena_join_string(arena, array_to_slice(compiler_dir_parts));
|
||||||
|
make_directory(cstr(base_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
String output_path_dir_parts[] = {
|
||||||
|
base_dir,
|
||||||
|
string_literal("/"),
|
||||||
build_mode_to_string(options.build_mode),
|
build_mode_to_string(options.build_mode),
|
||||||
string_literal("_"),
|
string_literal("_"),
|
||||||
options.has_debug_info ? string_literal("di") : string_literal("nodi"),
|
options.has_debug_info ? string_literal("di") : string_literal("nodi"),
|
||||||
};
|
};
|
||||||
auto output_path_dir = arena_join_string(arena, array_to_slice(output_path_dir_parts));
|
auto output_path_dir = arena_join_string(arena, array_to_slice(output_path_dir_parts));
|
||||||
|
|
||||||
make_directory(base_cache_dir);
|
|
||||||
|
|
||||||
if (is_compiler)
|
|
||||||
{
|
|
||||||
make_directory(base_cache_dir "/compiler");
|
|
||||||
}
|
|
||||||
|
|
||||||
make_directory(cstr(output_path_dir));
|
make_directory(cstr(output_path_dir));
|
||||||
|
|
||||||
String output_path_base_parts[] = {
|
String output_path_base_parts[] = {
|
||||||
@ -204,6 +221,16 @@ fn String compile_file(Arena* arena, Compile options)
|
|||||||
.value = cmake_prefix_path,
|
.value = cmake_prefix_path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (is_compiler)
|
||||||
|
{
|
||||||
|
auto cmake_prefix_path_cstr = os_get_environment_variable("CMAKE_PREFIX_PATH");
|
||||||
|
if (cmake_prefix_path_cstr)
|
||||||
|
{
|
||||||
|
auto cmake_prefix_path_string = c_string_to_slice(cmake_prefix_path_cstr);
|
||||||
|
cmake_prefix_path_definition.value = cmake_prefix_path_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String objects[] = {
|
String objects[] = {
|
||||||
output_object_path,
|
output_object_path,
|
||||||
};
|
};
|
||||||
@ -316,13 +343,28 @@ fn String compile_file(Arena* arena, Compile options)
|
|||||||
|
|
||||||
library_buffer[library_count] = string_literal("lldCommon");
|
library_buffer[library_count] = string_literal("lldCommon");
|
||||||
library_count += 1;
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = string_literal("lldCOFF");
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
library_buffer[library_count] = string_literal("lldELF");
|
library_buffer[library_count] = string_literal("lldELF");
|
||||||
library_count += 1;
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = string_literal("lldMachO");
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = string_literal("lldMinGW");
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = string_literal("lldWasm");
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = string_literal("llvm_bindings");
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
library_names = { library_buffer, library_count };
|
library_names = { library_buffer, library_count };
|
||||||
library_paths = { &llvm_bindings_library, 1 };
|
|
||||||
}
|
}
|
||||||
else if (base_name.equal(string_literal("c_abi")))
|
else if (base_name.equal(string_literal("tests")))
|
||||||
{
|
{
|
||||||
library_paths = { &c_abi_library, 1 };
|
library_paths = { &c_abi_library, 1 };
|
||||||
}
|
}
|
||||||
@ -341,6 +383,7 @@ fn String compile_file(Arena* arena, Compile options)
|
|||||||
.target = {
|
.target = {
|
||||||
.cpu = CPUArchitecture::x86_64,
|
.cpu = CPUArchitecture::x86_64,
|
||||||
.os = OperatingSystem::linux_,
|
.os = OperatingSystem::linux_,
|
||||||
|
.host_cpu_model = options.host_cpu_model,
|
||||||
},
|
},
|
||||||
.build_mode = options.build_mode,
|
.build_mode = options.build_mode,
|
||||||
.has_debug_info = options.has_debug_info,
|
.has_debug_info = options.has_debug_info,
|
||||||
@ -352,129 +395,7 @@ fn String compile_file(Arena* arena, Compile options)
|
|||||||
|
|
||||||
global_variable String names[] =
|
global_variable String names[] =
|
||||||
{
|
{
|
||||||
string_literal("minimal"),
|
string_literal("tests"),
|
||||||
string_literal("comments"),
|
|
||||||
string_literal("constant_add"),
|
|
||||||
string_literal("constant_and"),
|
|
||||||
string_literal("constant_div"),
|
|
||||||
string_literal("constant_mul"),
|
|
||||||
string_literal("constant_rem"),
|
|
||||||
string_literal("constant_or"),
|
|
||||||
string_literal("constant_sub"),
|
|
||||||
string_literal("constant_xor"),
|
|
||||||
string_literal("constant_shift_left"),
|
|
||||||
string_literal("constant_shift_right"),
|
|
||||||
string_literal("minimal_stack"),
|
|
||||||
string_literal("minimal_stack_arithmetic"),
|
|
||||||
string_literal("minimal_stack_arithmetic2"),
|
|
||||||
string_literal("minimal_stack_arithmetic3"),
|
|
||||||
string_literal("stack_negation"),
|
|
||||||
string_literal("stack_add"),
|
|
||||||
string_literal("stack_sub"),
|
|
||||||
string_literal("extend"),
|
|
||||||
string_literal("integer_max"),
|
|
||||||
string_literal("integer_hex"),
|
|
||||||
string_literal("basic_pointer"),
|
|
||||||
string_literal("basic_call"),
|
|
||||||
string_literal("basic_branch"),
|
|
||||||
string_literal("basic_array"),
|
|
||||||
string_literal("basic_enum"),
|
|
||||||
string_literal("basic_slice"),
|
|
||||||
string_literal("basic_string"),
|
|
||||||
string_literal("basic_varargs"),
|
|
||||||
string_literal("basic_while"),
|
|
||||||
string_literal("pointer"),
|
|
||||||
string_literal("pointer_cast"),
|
|
||||||
string_literal("u1_return"),
|
|
||||||
string_literal("local_type_inference"),
|
|
||||||
string_literal("global"),
|
|
||||||
string_literal("function_pointer"),
|
|
||||||
string_literal("extern"),
|
|
||||||
string_literal("byte_size"),
|
|
||||||
string_literal("argv"),
|
|
||||||
string_literal("assignment_operators"),
|
|
||||||
string_literal("not_pointer"),
|
|
||||||
string_literal("bits"),
|
|
||||||
string_literal("bits_no_backing_type"),
|
|
||||||
string_literal("bits_return_u1"),
|
|
||||||
string_literal("bits_zero"),
|
|
||||||
string_literal("comparison"),
|
|
||||||
string_literal("global_struct"),
|
|
||||||
string_literal("if_no_else"),
|
|
||||||
string_literal("if_no_else_void"),
|
|
||||||
string_literal("indirect"),
|
|
||||||
string_literal("indirect_struct"),
|
|
||||||
string_literal("indirect_varargs"),
|
|
||||||
string_literal("ret_c_bool"),
|
|
||||||
string_literal("return_type_builtin"),
|
|
||||||
string_literal("return_u64_u64"),
|
|
||||||
string_literal("select"),
|
|
||||||
string_literal("slice"),
|
|
||||||
string_literal("small_struct_ints"),
|
|
||||||
string_literal("struct_assignment"),
|
|
||||||
string_literal("struct"),
|
|
||||||
string_literal("struct_u64_u64"),
|
|
||||||
string_literal("struct_varargs"),
|
|
||||||
string_literal("struct_zero"),
|
|
||||||
string_literal("unreachable"),
|
|
||||||
string_literal("varargs"),
|
|
||||||
string_literal("c_abi0"),
|
|
||||||
string_literal("c_abi1"),
|
|
||||||
string_literal("c_med_struct_ints"),
|
|
||||||
string_literal("c_ret_struct_array"),
|
|
||||||
string_literal("c_split_struct_ints"),
|
|
||||||
string_literal("c_string_to_slice"),
|
|
||||||
string_literal("c_struct_with_array"),
|
|
||||||
string_literal("c_function_pointer"),
|
|
||||||
string_literal("basic_bool_call"),
|
|
||||||
string_literal("abi_enum_bool"),
|
|
||||||
string_literal("return_small_struct"),
|
|
||||||
string_literal("c_abi"),
|
|
||||||
string_literal("string_to_enum"),
|
|
||||||
string_literal("empty_if"),
|
|
||||||
string_literal("else_if"),
|
|
||||||
string_literal("else_if_complicated"),
|
|
||||||
string_literal("basic_shortcircuiting_if"),
|
|
||||||
string_literal("shortcircuiting_if"),
|
|
||||||
string_literal("field_access_left_assign"),
|
|
||||||
string_literal("for_each"),
|
|
||||||
string_literal("pointer_decay"),
|
|
||||||
string_literal("enum_name"),
|
|
||||||
string_literal("slice_of_slices"),
|
|
||||||
string_literal("type_alias"),
|
|
||||||
string_literal("integer_formats"),
|
|
||||||
string_literal("for_each_int"),
|
|
||||||
string_literal("bool_array"),
|
|
||||||
string_literal("basic_union"),
|
|
||||||
string_literal("break_continue"),
|
|
||||||
string_literal("constant_global_reference"),
|
|
||||||
string_literal("concat_logical_or"),
|
|
||||||
string_literal("strict_array_type"),
|
|
||||||
string_literal("pointer_struct_initialization"),
|
|
||||||
string_literal("slice_array_literal"),
|
|
||||||
string_literal("slice_only_start"),
|
|
||||||
|
|
||||||
string_literal("basic_macro"),
|
|
||||||
string_literal("generic_macro"),
|
|
||||||
|
|
||||||
string_literal("generic_pointer_macro"),
|
|
||||||
string_literal("noreturn_macro"),
|
|
||||||
string_literal("generic_pointer_array"),
|
|
||||||
|
|
||||||
string_literal("self_referential_struct"),
|
|
||||||
string_literal("forward_declared_type"),
|
|
||||||
|
|
||||||
string_literal("enum_array"),
|
|
||||||
string_literal("opaque"),
|
|
||||||
string_literal("basic_struct_passing"),
|
|
||||||
string_literal("enum_arbitrary_abi"),
|
|
||||||
string_literal("enum_debug_info"),
|
|
||||||
string_literal("return_array"),
|
|
||||||
string_literal("bool_pair"),
|
|
||||||
string_literal("min_max"),
|
|
||||||
string_literal("field_parent_pointer"),
|
|
||||||
string_literal("leading_trailing_zeroes"),
|
|
||||||
string_literal("pointer_sub"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
||||||
@ -517,6 +438,7 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
|
|
||||||
auto build_mode = BuildMode::debug_none;
|
auto build_mode = BuildMode::debug_none;
|
||||||
auto has_debug_info = true;
|
auto has_debug_info = true;
|
||||||
|
auto is_host_cpu_model = true;
|
||||||
|
|
||||||
if (arguments.length >= 4)
|
if (arguments.length >= 4)
|
||||||
{
|
{
|
||||||
@ -565,12 +487,30 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arguments.length >= 6)
|
||||||
|
{
|
||||||
|
auto is_host_cpu_model_string = c_string_to_slice(arguments[5]);
|
||||||
|
if (is_host_cpu_model_string.equal(string_literal("true")))
|
||||||
|
{
|
||||||
|
is_host_cpu_model = true;
|
||||||
|
}
|
||||||
|
else if (is_host_cpu_model_string.equal(string_literal("false")))
|
||||||
|
{
|
||||||
|
is_host_cpu_model = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bb_fail_with_message(string_literal("Wrong value for is_host_cpu_model\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto relative_file_path = c_string_to_slice(arguments[2]);
|
auto relative_file_path = c_string_to_slice(arguments[2]);
|
||||||
|
|
||||||
compile_file(arena, {
|
compile_file(arena, {
|
||||||
.relative_file_path = relative_file_path,
|
.relative_file_path = relative_file_path,
|
||||||
.build_mode = build_mode,
|
.build_mode = build_mode,
|
||||||
.has_debug_info = has_debug_info,
|
.has_debug_info = has_debug_info,
|
||||||
|
.host_cpu_model = is_host_cpu_model,
|
||||||
.silent = false,
|
.silent = false,
|
||||||
});
|
});
|
||||||
} break;
|
} break;
|
||||||
@ -596,11 +536,11 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts));
|
auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts));
|
||||||
|
|
||||||
auto executable_path = compile_file(arena, {
|
auto executable_path = compile_file(arena, {
|
||||||
.relative_file_path = relative_file_path,
|
.relative_file_path = relative_file_path,
|
||||||
.build_mode = build_mode,
|
.build_mode = build_mode,
|
||||||
.has_debug_info = has_debug_info,
|
.has_debug_info = has_debug_info,
|
||||||
.silent = true,
|
.silent = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
char* const arguments[] =
|
char* const arguments[] =
|
||||||
{
|
{
|
||||||
@ -630,6 +570,7 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
.relative_file_path = string_literal("src/compiler.bbb"),
|
.relative_file_path = string_literal("src/compiler.bbb"),
|
||||||
.build_mode = compiler_build_mode,
|
.build_mode = compiler_build_mode,
|
||||||
.has_debug_info = compiler_has_debug_info,
|
.has_debug_info = compiler_has_debug_info,
|
||||||
|
.host_cpu_model = true,
|
||||||
.silent = true,
|
.silent = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -247,6 +247,7 @@ struct Target
|
|||||||
{
|
{
|
||||||
CPUArchitecture cpu;
|
CPUArchitecture cpu;
|
||||||
OperatingSystem os;
|
OperatingSystem os;
|
||||||
|
bool host_cpu_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn Target target_get_native()
|
fn Target target_get_native()
|
||||||
@ -270,6 +271,7 @@ struct Compile
|
|||||||
String relative_file_path;
|
String relative_file_path;
|
||||||
BuildMode build_mode;
|
BuildMode build_mode;
|
||||||
bool has_debug_info;
|
bool has_debug_info;
|
||||||
|
bool host_cpu_model;
|
||||||
bool silent;
|
bool silent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -416,15 +416,23 @@ fn void llvm_initialize(Module* module)
|
|||||||
module->scope.llvm = di_compile_unit;
|
module->scope.llvm = di_compile_unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* target_triple = {};
|
const char* target_triple = {};
|
||||||
char* cpu_model = {};
|
const char* cpu_model = {};
|
||||||
char* cpu_features = {};
|
const char* cpu_features = {};
|
||||||
|
|
||||||
if (target_compare(module->target, target_get_native()))
|
if (target_compare(module->target, target_get_native()))
|
||||||
{
|
{
|
||||||
target_triple = llvm_global.host_triple;
|
target_triple = llvm_global.host_triple;
|
||||||
cpu_model = llvm_global.host_cpu_model;
|
if (module->target.host_cpu_model)
|
||||||
cpu_features = llvm_global.host_cpu_features;
|
{
|
||||||
|
cpu_model = llvm_global.host_cpu_model;
|
||||||
|
cpu_features = llvm_global.host_cpu_features;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpu_model = "generic";
|
||||||
|
cpu_features = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -9168,36 +9176,52 @@ struct ObjectGenerate
|
|||||||
bool has_debug_info;
|
bool has_debug_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn BBLLVMCodeGenerationPipelineResult generate_object(LLVMModuleRef module, LLVMTargetMachineRef target_machine, ObjectGenerate options)
|
fn bool generate_object(LLVMModuleRef module, LLVMTargetMachineRef target_machine, ObjectGenerate options)
|
||||||
{
|
{
|
||||||
if (options.run_optimization_passes)
|
if (options.run_optimization_passes)
|
||||||
{
|
{
|
||||||
// BBLLVM
|
|
||||||
bool prefer_speed = options.optimization_level == BBLLVMOptimizationLevel::O2 || options.optimization_level == BBLLVMOptimizationLevel::O3;
|
bool prefer_speed = options.optimization_level == BBLLVMOptimizationLevel::O2 || options.optimization_level == BBLLVMOptimizationLevel::O3;
|
||||||
BBLLVMOptimizationPipelineOptions optimization_options = {
|
auto pass_builder_options = LLVMCreatePassBuilderOptions();
|
||||||
.optimization_level = (u64)options.optimization_level,
|
LLVMPassBuilderOptionsSetVerifyEach(pass_builder_options, 1);
|
||||||
.debug_info = options.has_debug_info,
|
LLVMPassBuilderOptionsSetDebugLogging(pass_builder_options, 0);
|
||||||
.loop_unrolling = prefer_speed,
|
LLVMPassBuilderOptionsSetLoopInterleaving(pass_builder_options, prefer_speed);
|
||||||
.loop_interleaving = prefer_speed,
|
LLVMPassBuilderOptionsSetLoopVectorization(pass_builder_options, prefer_speed);
|
||||||
.loop_vectorization = prefer_speed,
|
LLVMPassBuilderOptionsSetSLPVectorization(pass_builder_options, prefer_speed);
|
||||||
.slp_vectorization = prefer_speed,
|
LLVMPassBuilderOptionsSetLoopUnrolling(pass_builder_options, prefer_speed);
|
||||||
.merge_functions = prefer_speed,
|
LLVMPassBuilderOptionsSetMergeFunctions(pass_builder_options, prefer_speed);
|
||||||
.call_graph_profile = false,
|
|
||||||
.unified_lto = false,
|
const char* passes;
|
||||||
.assignment_tracking = options.has_debug_info,
|
switch (options.optimization_level)
|
||||||
.verify_module = true,
|
{
|
||||||
};
|
case BBLLVMOptimizationLevel::O0: passes = "default<O0>"; break;
|
||||||
llvm_module_run_optimization_pipeline(module, target_machine, optimization_options);
|
case BBLLVMOptimizationLevel::O1: passes = "default<O1>"; break;
|
||||||
|
case BBLLVMOptimizationLevel::O2: passes = "default<O2>"; break;
|
||||||
|
case BBLLVMOptimizationLevel::O3: passes = "default<O3>"; break;
|
||||||
|
case BBLLVMOptimizationLevel::Os: passes = "default<Os>"; break;
|
||||||
|
case BBLLVMOptimizationLevel::Oz: passes = "default<Oz>"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto error = LLVMRunPasses(module, passes, target_machine, pass_builder_options);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BBLLVMCodeGenerationPipelineOptions code_generation_options = {
|
auto file_name = cstr(options.path);
|
||||||
.output_file_path = options.path,
|
char* error_message = 0;
|
||||||
.file_type = BBLLVMCodeGenerationFileType::object_file,
|
auto result = LLVMTargetMachineEmitToFile(target_machine, module, file_name, LLVMObjectFile, &error_message);
|
||||||
.optimize_when_possible = options.optimization_level > BBLLVMOptimizationLevel::O0,
|
if (result)
|
||||||
.verify_module = true,
|
{
|
||||||
};
|
assert(error_message);
|
||||||
auto result = llvm_module_run_code_generation_pipeline(module, target_machine, &code_generation_options);
|
trap();
|
||||||
return result;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!error_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void link(Module* module)
|
fn void link(Module* module)
|
||||||
@ -10049,10 +10073,7 @@ void emit(Module* module)
|
|||||||
.run_optimization_passes = module->build_mode != BuildMode::debug_none,
|
.run_optimization_passes = module->build_mode != BuildMode::debug_none,
|
||||||
.has_debug_info = module->has_debug_info,
|
.has_debug_info = module->has_debug_info,
|
||||||
});
|
});
|
||||||
if (object_generation_result != BBLLVMCodeGenerationPipelineResult::success)
|
assert(object_generation_result);
|
||||||
{
|
|
||||||
report_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
link(module);
|
link(module);
|
||||||
}
|
}
|
||||||
|
@ -225,3 +225,9 @@ Execution os_execute(Arena* arena, Slice<char* const> arguments, Slice<char* con
|
|||||||
|
|
||||||
return execution;
|
return execution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" char* getenv(const char*);
|
||||||
|
char* os_get_environment_variable(const char* env)
|
||||||
|
{
|
||||||
|
return getenv(env);
|
||||||
|
}
|
||||||
|
@ -719,3 +719,4 @@ struct Execution
|
|||||||
};
|
};
|
||||||
|
|
||||||
Execution os_execute(Arena* arena, Slice<char* const> arguments, Slice<char* const> environment, ExecuteOptions options);
|
Execution os_execute(Arena* arena, Slice<char* const> arguments, Slice<char* const> environment, ExecuteOptions options);
|
||||||
|
char* os_get_environment_variable(const char* env);
|
||||||
|
49
src/llvm.hpp
49
src/llvm.hpp
@ -7,6 +7,7 @@
|
|||||||
#include <llvm-c/Target.h>
|
#include <llvm-c/Target.h>
|
||||||
#include <llvm-c/Analysis.h>
|
#include <llvm-c/Analysis.h>
|
||||||
#include <llvm-c/TargetMachine.h>
|
#include <llvm-c/TargetMachine.h>
|
||||||
|
#include <llvm-c/Transforms/PassBuilder.h>
|
||||||
|
|
||||||
struct LLDResult
|
struct LLDResult
|
||||||
{
|
{
|
||||||
@ -15,31 +16,6 @@ struct LLDResult
|
|||||||
bool success;
|
bool success;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BBLLVMCodeGenerationPipelineResult : u8
|
|
||||||
{
|
|
||||||
success = 0,
|
|
||||||
failed_to_create_file = 1,
|
|
||||||
failed_to_add_emit_passes = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BBLLVMCodeGenerationFileType : u8
|
|
||||||
{
|
|
||||||
assembly_file = 0,
|
|
||||||
object_file = 1,
|
|
||||||
null = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BBLLVMCodeGenerationPipelineOptions
|
|
||||||
{
|
|
||||||
String output_dwarf_file_path;
|
|
||||||
String output_file_path;
|
|
||||||
BBLLVMCodeGenerationFileType file_type;
|
|
||||||
bool optimize_when_possible;
|
|
||||||
bool verify_module;
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(BBLLVMCodeGenerationPipelineOptions) == 5 * sizeof(u64));
|
|
||||||
|
|
||||||
enum class BBLLVMOptimizationLevel : u8
|
enum class BBLLVMOptimizationLevel : u8
|
||||||
{
|
{
|
||||||
O0 = 0,
|
O0 = 0,
|
||||||
@ -50,26 +26,6 @@ enum class BBLLVMOptimizationLevel : u8
|
|||||||
Oz = 5,
|
Oz = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BB_LLVM_OPTIMIZATION_PIPELINE_OPTIONS_PADDING_BIT_COUNT (51)
|
|
||||||
struct BBLLVMOptimizationPipelineOptions
|
|
||||||
{
|
|
||||||
u64 optimization_level:3;
|
|
||||||
u64 debug_info:1;
|
|
||||||
u64 loop_unrolling:1;
|
|
||||||
u64 loop_interleaving:1;
|
|
||||||
u64 loop_vectorization:1;
|
|
||||||
u64 slp_vectorization:1;
|
|
||||||
u64 merge_functions:1;
|
|
||||||
u64 call_graph_profile:1;
|
|
||||||
u64 unified_lto:1;
|
|
||||||
u64 assignment_tracking:1;
|
|
||||||
u64 verify_module:1;
|
|
||||||
u64 reserved:BB_LLVM_OPTIMIZATION_PIPELINE_OPTIONS_PADDING_BIT_COUNT;
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(BBLLVMOptimizationPipelineOptions) == sizeof(u64));
|
|
||||||
static_assert(BB_LLVM_OPTIMIZATION_PIPELINE_OPTIONS_PADDING_BIT_COUNT == 51);
|
|
||||||
|
|
||||||
enum class DwarfType
|
enum class DwarfType
|
||||||
{
|
{
|
||||||
void_type = 0x0,
|
void_type = 0x0,
|
||||||
@ -123,9 +79,6 @@ extern "C" LLVMValueRef llvm_find_return_value_dominating_store(LLVMBuilderRef b
|
|||||||
|
|
||||||
extern "C" void llvm_subprogram_replace_type(LLVMMetadataRef subprogram, LLVMMetadataRef subroutine_type);
|
extern "C" void llvm_subprogram_replace_type(LLVMMetadataRef subprogram, LLVMMetadataRef subroutine_type);
|
||||||
|
|
||||||
extern "C" void llvm_module_run_optimization_pipeline(LLVMModuleRef module, LLVMTargetMachineRef target_machine, BBLLVMOptimizationPipelineOptions options);
|
|
||||||
extern "C" BBLLVMCodeGenerationPipelineResult llvm_module_run_code_generation_pipeline(LLVMModuleRef m, LLVMTargetMachineRef tm, const BBLLVMCodeGenerationPipelineOptions* options);
|
|
||||||
|
|
||||||
#define lld_api_args() char* const* argument_pointer, u64 argument_count, bool exit_early, bool disable_output
|
#define lld_api_args() char* const* argument_pointer, u64 argument_count, bool exit_early, bool disable_output
|
||||||
#define lld_api_function_decl(link_name) LLDResult lld_ ## link_name ## _link(lld_api_args())
|
#define lld_api_function_decl(link_name) LLDResult lld_ ## link_name ## _link(lld_api_args())
|
||||||
extern "C" lld_api_function_decl(elf);
|
extern "C" lld_api_function_decl(elf);
|
||||||
|
@ -999,7 +999,7 @@ fn Type* parse_type(Module* module, Scope* scope)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (start_character == '#')
|
else if (start_character == '@')
|
||||||
{
|
{
|
||||||
module->offset += 1;
|
module->offset += 1;
|
||||||
auto identifier = parse_identifier(module);
|
auto identifier = parse_identifier(module);
|
||||||
@ -1167,7 +1167,7 @@ fn Token tokenize(Module* module)
|
|||||||
.id = id,
|
.id = id,
|
||||||
};
|
};
|
||||||
} break;
|
} break;
|
||||||
case '#':
|
case '@':
|
||||||
{
|
{
|
||||||
module->offset += 1;
|
module->offset += 1;
|
||||||
if (is_identifier_start(module->content[module->offset]))
|
if (is_identifier_start(module->content[module->offset]))
|
||||||
@ -2631,7 +2631,7 @@ fn Statement* parse_statement(Module* module, Scope* scope)
|
|||||||
statement->local = local;
|
statement->local = local;
|
||||||
statement->id = StatementId::local;
|
statement->id = StatementId::local;
|
||||||
} break;
|
} break;
|
||||||
case '#':
|
case '@':
|
||||||
{
|
{
|
||||||
statement->expression = parse_value(module, scope, {});
|
statement->expression = parse_value(module, scope, {});
|
||||||
statement->id = StatementId::expression;
|
statement->id = StatementId::expression;
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
Foo = enum {
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
c,
|
|
||||||
d,
|
|
||||||
e,
|
|
||||||
f,
|
|
||||||
g,
|
|
||||||
}
|
|
||||||
|
|
||||||
S = struct
|
|
||||||
{
|
|
||||||
enum: Foo,
|
|
||||||
some_boolean: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>s: S = {
|
|
||||||
.enum = .f,
|
|
||||||
.some_boolean = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
require(s.enum == .f);
|
|
||||||
require(s.some_boolean);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] (argument_count: u32, argument_pointer: &&u8) s32
|
|
||||||
{
|
|
||||||
if (argument_count != 1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
>arg = argument_pointer[0];
|
|
||||||
if (arg != argument_pointer[0])
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
unsigned = fn(n: s32) s32
|
|
||||||
{
|
|
||||||
>result: u32 = #extend(n);
|
|
||||||
result >>= 1;
|
|
||||||
result <<= 1;
|
|
||||||
result ^= 1;
|
|
||||||
result |= 1;
|
|
||||||
result &= 1;
|
|
||||||
result += 1;
|
|
||||||
result -= 1;
|
|
||||||
result /= 1;
|
|
||||||
result %= 1;
|
|
||||||
result *= 0;
|
|
||||||
|
|
||||||
return #extend(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0;
|
|
||||||
>pointer = &result;
|
|
||||||
pointer -= 1;
|
|
||||||
pointer += 1;
|
|
||||||
result >>= 1;
|
|
||||||
result <<= 1;
|
|
||||||
result ^= 1;
|
|
||||||
result |= 1;
|
|
||||||
result &= 1;
|
|
||||||
result += 1;
|
|
||||||
result -= 1;
|
|
||||||
result /= 1;
|
|
||||||
result %= 1;
|
|
||||||
result *= 0;
|
|
||||||
return unsigned(result);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>array: [_]s32 = [3, 2, 1, 0];
|
|
||||||
return array[3];
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok) #trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
bb_bool = fn (x: u8) void
|
|
||||||
{
|
|
||||||
require(#truncate(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
bb_bool(1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s32 = 1;
|
|
||||||
if (result != 1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
foo = fn() s32
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn[cc(c)] () s32
|
|
||||||
{
|
|
||||||
return foo();
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
E = enum
|
|
||||||
{
|
|
||||||
zero = 0,
|
|
||||||
one = 1,
|
|
||||||
two = 2,
|
|
||||||
three = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: E = .three;
|
|
||||||
>b: E = .two;
|
|
||||||
>c: E = .one;
|
|
||||||
>a_int: s32 = #extend(#int_from_enum(a));
|
|
||||||
>b_int: s32 = #extend(#int_from_enum(b));
|
|
||||||
>c_int: s32 = #extend(#int_from_enum(c));
|
|
||||||
return a_int - (b_int + c_int);
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
sub = macro (a: s32, b: s32) s32
|
|
||||||
{
|
|
||||||
return a - b;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a = sub(1, 1);
|
|
||||||
>b = sub(2, 2);
|
|
||||||
return a + b;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
>pointer = &a;
|
|
||||||
return pointer.&;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] (argument_count: u32) s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
if (argument_count != 3 and? argument_count != 2)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
slice_receiver = fn (slice: []u8) void
|
|
||||||
{
|
|
||||||
require(slice.length == 3);
|
|
||||||
require(slice[0] == 0);
|
|
||||||
require(slice[1] == 1);
|
|
||||||
require(slice[2] == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: [_]u8 = [0, 1, 2];
|
|
||||||
slice_receiver(a[..]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>string = "abc";
|
|
||||||
require(string[0] == 'a');
|
|
||||||
require(string[1] == 'b');
|
|
||||||
require(string[2] == 'c');
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
CallingConvention = enum
|
|
||||||
{
|
|
||||||
c,
|
|
||||||
}
|
|
||||||
|
|
||||||
InlineBehavior = enum
|
|
||||||
{
|
|
||||||
default = 0,
|
|
||||||
always_inline = 1,
|
|
||||||
no_inline = 2,
|
|
||||||
inline_hint = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionAttributes = struct
|
|
||||||
{
|
|
||||||
inline_behavior: InlineBehavior,
|
|
||||||
naked: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
Type = struct;
|
|
||||||
|
|
||||||
TypeId = enum
|
|
||||||
{
|
|
||||||
void,
|
|
||||||
noreturn,
|
|
||||||
forward_declaration,
|
|
||||||
integer,
|
|
||||||
function,
|
|
||||||
pointer,
|
|
||||||
array,
|
|
||||||
enum,
|
|
||||||
struct,
|
|
||||||
bits,
|
|
||||||
alias,
|
|
||||||
union,
|
|
||||||
unresolved,
|
|
||||||
vector,
|
|
||||||
floating_point,
|
|
||||||
enum_array,
|
|
||||||
opaque,
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeInteger = struct
|
|
||||||
{
|
|
||||||
bit_count: u32,
|
|
||||||
signed: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
TypePointer = struct
|
|
||||||
{
|
|
||||||
element_type: &Type,
|
|
||||||
next: &Type,
|
|
||||||
}
|
|
||||||
|
|
||||||
AbiRegisterCountSystemV = struct
|
|
||||||
{
|
|
||||||
gpr: u32,
|
|
||||||
sse: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
AbiRegisterCount = union
|
|
||||||
{
|
|
||||||
system_v: AbiRegisterCountSystemV,
|
|
||||||
};
|
|
||||||
|
|
||||||
AbiInformation = struct
|
|
||||||
{
|
|
||||||
foo: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeFunction = struct
|
|
||||||
{
|
|
||||||
semantic_return_type: &Type,
|
|
||||||
semantic_argument_types: []&Type,
|
|
||||||
calling_convention: CallingConvention,
|
|
||||||
is_variable_arguments: u1,
|
|
||||||
|
|
||||||
abi_argument_types: []&Type,
|
|
||||||
abi_return_type: &Type,
|
|
||||||
available_registers: AbiRegisterCount,
|
|
||||||
argument_abis: []AbiInformation,
|
|
||||||
return_abi: AbiInformation,
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeContent = union
|
|
||||||
{
|
|
||||||
integer: TypeInteger,
|
|
||||||
function: TypeFunction,
|
|
||||||
pointer: TypePointer,
|
|
||||||
}
|
|
||||||
|
|
||||||
Type = struct
|
|
||||||
{
|
|
||||||
content: TypeContent,
|
|
||||||
id: TypeId,
|
|
||||||
name: []u8,
|
|
||||||
next: &Type,
|
|
||||||
}
|
|
||||||
|
|
||||||
give_me_string = fn () []u8
|
|
||||||
{
|
|
||||||
return "foooo";
|
|
||||||
}
|
|
||||||
|
|
||||||
get_type = fn (src: &Type, type: Type) &Type
|
|
||||||
{
|
|
||||||
src.& = type;
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok) #trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>buffer: Type = undefined;
|
|
||||||
>pointer = &buffer;
|
|
||||||
require(pointer == &buffer);
|
|
||||||
require(pointer != zero);
|
|
||||||
>result = get_type(pointer, {
|
|
||||||
.content = {
|
|
||||||
.pointer = {
|
|
||||||
.element_type = pointer,
|
|
||||||
zero,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.id = .pointer,
|
|
||||||
.name = give_me_string(),
|
|
||||||
zero,
|
|
||||||
});
|
|
||||||
|
|
||||||
require(pointer != zero);
|
|
||||||
require(pointer == &buffer);
|
|
||||||
require(buffer.content.pointer.element_type == pointer);
|
|
||||||
require(buffer.id == .pointer);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
E = enum
|
|
||||||
{
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
c,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>some_enum: E = .a;
|
|
||||||
switch (some_enum)
|
|
||||||
{
|
|
||||||
.a =>
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
.b =>
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
},
|
|
||||||
.c =>
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
U = union
|
|
||||||
{
|
|
||||||
s: s32,
|
|
||||||
u: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>my_union: U = {
|
|
||||||
.s = -1,
|
|
||||||
};
|
|
||||||
if (my_union.s != -1) #trap();
|
|
||||||
if (my_union.u != 0xffffffff) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
va_arg_fn = fn [cc(c)] (first_arg: u32, ...) void
|
|
||||||
{
|
|
||||||
if (first_arg != 123456789)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
>va = #va_start();
|
|
||||||
|
|
||||||
>a = #va_arg(&va, u32);
|
|
||||||
if (a != 987654321)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
>first_arg_b = #va_arg(&va, u32);
|
|
||||||
if (first_arg_b != 123456789)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>first_arg: u32 = 123456789;
|
|
||||||
>a: u32 = 987654321;
|
|
||||||
va_arg_fn(first_arg, a, first_arg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
c_string_length = fn (c_string: &u8) u64
|
|
||||||
{
|
|
||||||
>it = c_string;
|
|
||||||
|
|
||||||
while (it.&)
|
|
||||||
{
|
|
||||||
it = it + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return #int_from_pointer(it) - #int_from_pointer(c_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn (argument_count: u32, argument_pointer: &&u8) s32
|
|
||||||
{
|
|
||||||
if (argument_count == 0)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>first_arg = argument_pointer[0];
|
|
||||||
if (!first_arg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>arg_length = c_string_length(first_arg);
|
|
||||||
if (arg_length == 0)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first_arg[arg_length] != 0)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
BitField = bits u8
|
|
||||||
{
|
|
||||||
a: u2,
|
|
||||||
b: u2,
|
|
||||||
c: u2,
|
|
||||||
d: u2,
|
|
||||||
};
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>b: BitField = {
|
|
||||||
.a = 3,
|
|
||||||
.b = 2,
|
|
||||||
.c = 2,
|
|
||||||
.d = 3,
|
|
||||||
};
|
|
||||||
return #extend((b.a - b.d) + (b.b - b.c));
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
A = bits {
|
|
||||||
a: u1,
|
|
||||||
b: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: A = {
|
|
||||||
.a = 1,
|
|
||||||
.b = 1,
|
|
||||||
};
|
|
||||||
return #extend(a.a - a.b);
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
S = bits u32
|
|
||||||
{
|
|
||||||
a: u1,
|
|
||||||
b: u1,
|
|
||||||
c: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
foo = fn () u1
|
|
||||||
{
|
|
||||||
>a: S = { .a = 1, .b = 1, .c = 0 };
|
|
||||||
return a.c;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return #extend(foo() == 1);
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
S = bits
|
|
||||||
{
|
|
||||||
a: u1,
|
|
||||||
b: u1,
|
|
||||||
c: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn () s32
|
|
||||||
{
|
|
||||||
>a: S = zero;
|
|
||||||
|
|
||||||
require(a.a == 0);
|
|
||||||
require(a.b == 0);
|
|
||||||
require(a.c == 0);
|
|
||||||
|
|
||||||
>b: S = {
|
|
||||||
.a = 1,
|
|
||||||
.b = 1,
|
|
||||||
zero,
|
|
||||||
};
|
|
||||||
|
|
||||||
require(b.a == 1);
|
|
||||||
require(b.b == 1);
|
|
||||||
require(b.c == 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>signs: [2]u1 = [0, 0];
|
|
||||||
>accumulator: s32 = 0;
|
|
||||||
|
|
||||||
for (s: signs)
|
|
||||||
{
|
|
||||||
accumulator += #extend(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
return accumulator;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
BoolPair = struct
|
|
||||||
{
|
|
||||||
a: u1,
|
|
||||||
b: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
bool_pair = fn () BoolPair
|
|
||||||
{
|
|
||||||
return { .a = 0, .b = 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result = bool_pair();
|
|
||||||
if (result.a) #trap();
|
|
||||||
if (!result.b) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
|
|
||||||
while (a < 10)
|
|
||||||
{
|
|
||||||
if (a == 3)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
a += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
>b: s32 = 2;
|
|
||||||
for (i: 0..10)
|
|
||||||
{
|
|
||||||
if (b == 2)
|
|
||||||
{
|
|
||||||
b += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a - b;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = #byte_size(s32);
|
|
||||||
>b: s32 = #byte_size(s32);
|
|
||||||
return a - b;
|
|
||||||
}
|
|
539
tests/c_abi.bbb
539
tests/c_abi.bbb
@ -1,539 +0,0 @@
|
|||||||
Struct_u64_u64 = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
BigStruct = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u64,
|
|
||||||
c: u64,
|
|
||||||
d: u64,
|
|
||||||
e: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallPackedStruct = bits u8
|
|
||||||
{
|
|
||||||
a: u2,
|
|
||||||
b: u2,
|
|
||||||
c: u2,
|
|
||||||
d: u2,
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallStructInts = struct
|
|
||||||
{
|
|
||||||
a: u8,
|
|
||||||
b: u8,
|
|
||||||
c: u8,
|
|
||||||
d: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
SplitStructInt = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u8,
|
|
||||||
c: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
MedStructInts = struct
|
|
||||||
{
|
|
||||||
x: s32,
|
|
||||||
y: s32,
|
|
||||||
z: s32,
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect = struct
|
|
||||||
{
|
|
||||||
left: u32,
|
|
||||||
right: u32,
|
|
||||||
top: u32,
|
|
||||||
bottom: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
StructWithArray = struct
|
|
||||||
{
|
|
||||||
a: s32,
|
|
||||||
padding: [4]u8,
|
|
||||||
b: s64,
|
|
||||||
}
|
|
||||||
|
|
||||||
ByRef = struct
|
|
||||||
{
|
|
||||||
val: s32,
|
|
||||||
arr: [15]s32,
|
|
||||||
}
|
|
||||||
|
|
||||||
ByValOrigin = struct
|
|
||||||
{
|
|
||||||
x: u64,
|
|
||||||
y: u64,
|
|
||||||
z: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
ByValSize = struct
|
|
||||||
{
|
|
||||||
width: u64,
|
|
||||||
height: u64,
|
|
||||||
depth: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
ByVal = struct
|
|
||||||
{
|
|
||||||
origin: ByValOrigin,
|
|
||||||
size: ByValSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
[extern] run_c_tests = fn [cc(c)] () void;
|
|
||||||
|
|
||||||
[extern] c_u8 = fn [cc(c)] (x: u8) void;
|
|
||||||
[extern] c_u16 = fn [cc(c)] (x: u16) void;
|
|
||||||
[extern] c_u32 = fn [cc(c)] (x: u32) void;
|
|
||||||
[extern] c_u64 = fn [cc(c)] (x: u64) void;
|
|
||||||
|
|
||||||
[extern] c_s8 = fn [cc(c)] (x: s8) void;
|
|
||||||
[extern] c_s16 = fn [cc(c)] (x: s16) void;
|
|
||||||
[extern] c_s32 = fn [cc(c)] (x: s32) void;
|
|
||||||
[extern] c_s64 = fn [cc(c)] (x: s64) void;
|
|
||||||
|
|
||||||
[extern] c_bool = fn [cc(c)] (x: u8) void;
|
|
||||||
|
|
||||||
[extern] c_five_integers = fn [cc(c)] (a: s32, b: s32, c: s32, d: s32, e: s32) void;
|
|
||||||
[extern] c_ret_struct_u64_u64 = fn [cc(c)] () Struct_u64_u64;
|
|
||||||
|
|
||||||
[extern] c_struct_u64_u64_0 = fn [cc(c)] (a: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_1 = fn [cc(c)] (a: u64, b: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_2 = fn [cc(c)] (a: u64, b: u64, c: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_3 = fn [cc(c)] (a: u64, b: u64, c: u64, d: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_4 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_5 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_6 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_7 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: Struct_u64_u64) void;
|
|
||||||
[extern] c_struct_u64_u64_8 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: u64, i: Struct_u64_u64) void;
|
|
||||||
|
|
||||||
[extern] c_big_struct = fn [cc(c)] (x: BigStruct) void;
|
|
||||||
[extern] c_small_struct_ints = fn [cc(c)] (x: SmallStructInts) void;
|
|
||||||
[extern] c_ret_small_struct_ints = fn [cc(c)] () SmallStructInts;
|
|
||||||
[extern] c_med_struct_ints = fn [cc(c)] (x: MedStructInts) void;
|
|
||||||
[extern] c_ret_med_struct_ints = fn [cc(c)] () MedStructInts;
|
|
||||||
[extern] c_small_packed_struct = fn [cc(c)] (x: SmallPackedStruct) void;
|
|
||||||
[extern] c_ret_small_packed_struct = fn [cc(c)] () SmallPackedStruct;
|
|
||||||
[extern] c_split_struct_ints = fn [cc(c)] (x: SplitStructInt) void;
|
|
||||||
[extern] c_big_struct_both = fn [cc(c)] (x: BigStruct) BigStruct;
|
|
||||||
[extern] c_multiple_struct_ints = fn [cc(c)] (a: Rect, b: Rect) void;
|
|
||||||
|
|
||||||
[extern] c_ret_bool = fn [cc(c)] () u8;
|
|
||||||
|
|
||||||
[extern] c_ret_u8 = fn [cc(c)] () u8;
|
|
||||||
[extern] c_ret_u16 = fn [cc(c)] () u16;
|
|
||||||
[extern] c_ret_u32 = fn [cc(c)] () u32;
|
|
||||||
[extern] c_ret_u64 = fn [cc(c)] () u64;
|
|
||||||
|
|
||||||
[extern] c_ret_s8 = fn [cc(c)] () s8;
|
|
||||||
[extern] c_ret_s16 = fn [cc(c)] () s16;
|
|
||||||
[extern] c_ret_s32 = fn [cc(c)] () s32;
|
|
||||||
[extern] c_ret_s64 = fn [cc(c)] () s64;
|
|
||||||
|
|
||||||
[extern] c_struct_with_array = fn [cc(c)] (x: StructWithArray) void;
|
|
||||||
[extern] c_ret_struct_with_array = fn [cc(c)] () StructWithArray;
|
|
||||||
|
|
||||||
[extern] c_modify_by_ref_param = fn [cc(c)] (x: ByRef) ByRef;
|
|
||||||
[extern] c_func_ptr_byval = fn [cc(c)] (a: u64, b: u64, c: ByVal, d: u64, e: u64, f: u64) void;
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
run_c_tests();
|
|
||||||
c_u8(0xff);
|
|
||||||
c_u16(0xfffe);
|
|
||||||
c_u32(0xfffffffd);
|
|
||||||
c_u64(0xfffffffffffffffc);
|
|
||||||
|
|
||||||
//if (has_i128) {
|
|
||||||
// c_struct_u128({ .value = 0xfffffffffffffffc, });
|
|
||||||
//}
|
|
||||||
|
|
||||||
c_s8(-1);
|
|
||||||
c_s16(-2);
|
|
||||||
c_s32(-3);
|
|
||||||
c_s64(-4);
|
|
||||||
|
|
||||||
//if (has_i128) {
|
|
||||||
// c_struct_i128({ .value = -6, });
|
|
||||||
//}
|
|
||||||
|
|
||||||
c_bool(1);
|
|
||||||
|
|
||||||
c_five_integers(12, 34, 56, 78, 90);
|
|
||||||
|
|
||||||
>s = c_ret_struct_u64_u64();
|
|
||||||
require(s.a == 21);
|
|
||||||
require(s.b == 22);
|
|
||||||
c_struct_u64_u64_0({ .a = 23, .b = 24, });
|
|
||||||
c_struct_u64_u64_1(0, { .a = 25, .b = 26, });
|
|
||||||
c_struct_u64_u64_2(0, 1, { .a = 27, .b = 28, });
|
|
||||||
c_struct_u64_u64_3(0, 1, 2, { .a = 29, .b = 30, });
|
|
||||||
c_struct_u64_u64_4(0, 1, 2, 3, { .a = 31, .b = 32, });
|
|
||||||
c_struct_u64_u64_5(0, 1, 2, 3, 4, { .a = 33, .b = 34, });
|
|
||||||
c_struct_u64_u64_6(0, 1, 2, 3, 4, 5, { .a = 35, .b = 36, });
|
|
||||||
c_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, { .a = 37, .b = 38, });
|
|
||||||
c_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, { .a = 39, .b = 40, });
|
|
||||||
|
|
||||||
>big_struct: BigStruct = {
|
|
||||||
.a = 1,
|
|
||||||
.b = 2,
|
|
||||||
.c = 3,
|
|
||||||
.d = 4,
|
|
||||||
.e = 5,
|
|
||||||
};
|
|
||||||
c_big_struct(big_struct);
|
|
||||||
|
|
||||||
>small: SmallStructInts = {
|
|
||||||
.a = 1,
|
|
||||||
.b = 2,
|
|
||||||
.c = 3,
|
|
||||||
.d = 4,
|
|
||||||
};
|
|
||||||
c_small_struct_ints(small);
|
|
||||||
>small2 = c_ret_small_struct_ints();
|
|
||||||
require(small2.a == 1);
|
|
||||||
require(small2.b == 2);
|
|
||||||
require(small2.c == 3);
|
|
||||||
require(small2.d == 4);
|
|
||||||
|
|
||||||
>med: MedStructInts = {
|
|
||||||
.x = 1,
|
|
||||||
.y = 2,
|
|
||||||
.z = 3,
|
|
||||||
};
|
|
||||||
c_med_struct_ints(med);
|
|
||||||
>med2 = c_ret_med_struct_ints();
|
|
||||||
require(med2.x == 1);
|
|
||||||
require(med2.y == 2);
|
|
||||||
require(med2.z == 3);
|
|
||||||
|
|
||||||
>p: SmallPackedStruct = { .a = 0, .b = 1, .c = 2, .d = 3, };
|
|
||||||
c_small_packed_struct(p);
|
|
||||||
>p2 = c_ret_small_packed_struct();
|
|
||||||
require(p2.a == 0);
|
|
||||||
require(p2.b == 1);
|
|
||||||
require(p2.c == 2);
|
|
||||||
require(p2.d == 3);
|
|
||||||
|
|
||||||
>split: SplitStructInt = {
|
|
||||||
.a = 1234,
|
|
||||||
.b = 100,
|
|
||||||
.c = 1337,
|
|
||||||
};
|
|
||||||
c_split_struct_ints(split);
|
|
||||||
|
|
||||||
> big: BigStruct = {
|
|
||||||
.a = 1,
|
|
||||||
.b = 2,
|
|
||||||
.c = 3,
|
|
||||||
.d = 4,
|
|
||||||
.e = 5,
|
|
||||||
};
|
|
||||||
>big2 = c_big_struct_both(big);
|
|
||||||
require(big2.a == 10);
|
|
||||||
require(big2.b == 11);
|
|
||||||
require(big2.c == 12);
|
|
||||||
require(big2.d == 13);
|
|
||||||
require(big2.e == 14);
|
|
||||||
|
|
||||||
>r1: Rect = {
|
|
||||||
.left = 1,
|
|
||||||
.right = 21,
|
|
||||||
.top = 16,
|
|
||||||
.bottom = 4,
|
|
||||||
};
|
|
||||||
>r2: Rect = {
|
|
||||||
.left = 178,
|
|
||||||
.right = 189,
|
|
||||||
.top = 21,
|
|
||||||
.bottom = 15,
|
|
||||||
};
|
|
||||||
c_multiple_struct_ints(r1, r2);
|
|
||||||
|
|
||||||
require(c_ret_bool() == 1);
|
|
||||||
|
|
||||||
require(c_ret_u8() == 0xff);
|
|
||||||
require(c_ret_u16() == 0xffff);
|
|
||||||
require(c_ret_u32() == 0xffffffff);
|
|
||||||
require(c_ret_u64() == 0xffffffffffffffff);
|
|
||||||
|
|
||||||
require(c_ret_s8() == -1);
|
|
||||||
require(c_ret_s16() == -1);
|
|
||||||
require(c_ret_s32() == -1);
|
|
||||||
require(c_ret_s64() == -1);
|
|
||||||
|
|
||||||
c_struct_with_array({ .a = 1, .padding = [0, 0, 0, 0], .b = 2, });
|
|
||||||
|
|
||||||
>x = c_ret_struct_with_array();
|
|
||||||
require(x.a == 4);
|
|
||||||
require(x.b == 155);
|
|
||||||
|
|
||||||
>res = c_modify_by_ref_param({ .val = 1, .arr = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] });
|
|
||||||
require(res.val == 42);
|
|
||||||
|
|
||||||
>function_pointer = &c_func_ptr_byval;
|
|
||||||
function_pointer(1, 2, { .origin = { .x = 9, .y = 10, .z = 11, }, .size = { .width = 12, .height = 13, .depth = 14, }, }, 3, 4, 5);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_u8 = fn [cc(c)] (x: u8) void
|
|
||||||
{
|
|
||||||
require(x == 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_u16 = fn [cc(c)] (x: u16) void
|
|
||||||
{
|
|
||||||
require(x == 0xfffe);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_u32 = fn [cc(c)] (x: u32) void
|
|
||||||
{
|
|
||||||
require(x == 0xfffffffd);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_u64 = fn [cc(c)] (x: u64) void
|
|
||||||
{
|
|
||||||
require(x == 0xfffffffffffffffc);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_s8 = fn [cc(c)] (x: s8) void
|
|
||||||
{
|
|
||||||
require(x == -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_s16 = fn [cc(c)] (x: s16) void
|
|
||||||
{
|
|
||||||
require(x == -2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_s32 = fn [cc(c)] (x: s32) void
|
|
||||||
{
|
|
||||||
require(x == -3);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_s64 = fn [cc(c)] (x: s64) void
|
|
||||||
{
|
|
||||||
require(x == -4);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ptr = fn [cc(c)] (x: &u8) void
|
|
||||||
{
|
|
||||||
require(#int_from_pointer(x) == 0xdeadbeef);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_five_integers = fn [cc(c)] (a: s32, b: s32, c: s32, d: s32, e: s32) void
|
|
||||||
{
|
|
||||||
require(a == 12);
|
|
||||||
require(b == 34);
|
|
||||||
require(c == 56);
|
|
||||||
require(d == 78);
|
|
||||||
require(e == 90);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_bool = fn [cc(c)] (x: u8) void
|
|
||||||
{
|
|
||||||
require(#truncate(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_struct_u64_u64 = fn [cc(c)] () Struct_u64_u64
|
|
||||||
{
|
|
||||||
return { .a = 1, .b = 2, };
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_0 = fn [cc(c)] (s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 3);
|
|
||||||
require(s.b == 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_1 = fn [cc(c)] (_: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 5);
|
|
||||||
require(s.b == 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_2 = fn [cc(c)] (_: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 7);
|
|
||||||
require(s.b == 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_3 = fn [cc(c)] (_: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 9);
|
|
||||||
require(s.b == 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_4 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 11);
|
|
||||||
require(s.b == 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_5 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 13);
|
|
||||||
require(s.b == 14);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_6 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 15);
|
|
||||||
require(s.b == 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_7 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 17);
|
|
||||||
require(s.b == 18);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_struct_u64_u64_8 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 19);
|
|
||||||
require(s.b == 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_big_struct = fn [cc(c)] (x: BigStruct) void
|
|
||||||
{
|
|
||||||
require(x.a == 1);
|
|
||||||
require(x.b == 2);
|
|
||||||
require(x.c == 3);
|
|
||||||
require(x.d == 4);
|
|
||||||
require(x.e == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_small_packed_struct = fn [cc(c)] (x: SmallPackedStruct) void
|
|
||||||
{
|
|
||||||
require(x.a == 0);
|
|
||||||
require(x.b == 1);
|
|
||||||
require(x.c == 2);
|
|
||||||
require(x.d == 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_split_struct_ints = fn [cc(c)] (x: SplitStructInt) void
|
|
||||||
{
|
|
||||||
require(x.a == 1234);
|
|
||||||
require(x.b == 100);
|
|
||||||
require(x.c == 1337);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_big_struct_both = fn [cc(c)] (x: BigStruct) BigStruct
|
|
||||||
{
|
|
||||||
require(x.a == 30);
|
|
||||||
require(x.b == 31);
|
|
||||||
require(x.c == 32);
|
|
||||||
require(x.d == 33);
|
|
||||||
require(x.e == 34);
|
|
||||||
>s: BigStruct = {
|
|
||||||
.a = 20,
|
|
||||||
.b = 21,
|
|
||||||
.c = 22,
|
|
||||||
.d = 23,
|
|
||||||
.e = 24,
|
|
||||||
};
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_bool = fn [cc(c)] () u8
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_u8 = fn [cc(c)] () u8
|
|
||||||
{
|
|
||||||
return 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_u16 = fn [cc(c)] () u16
|
|
||||||
{
|
|
||||||
return 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_u32 = fn [cc(c)] () u32
|
|
||||||
{
|
|
||||||
return 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_u64 = fn [cc(c)] () u64
|
|
||||||
{
|
|
||||||
return 0xffffffffffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_s8 = fn [cc(c)] () s8
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_s16 = fn [cc(c)] () s16
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_s32 = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_s64 = fn [cc(c)] () s64
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_small_struct_ints = fn [cc(c)] () SmallStructInts
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.a = 1,
|
|
||||||
.b = 2,
|
|
||||||
.c = 3,
|
|
||||||
.d = 4,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_ret_med_struct_ints = fn [cc(c)] () MedStructInts
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.x = 1,
|
|
||||||
.y = 2,
|
|
||||||
.z = 3,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_multiple_struct_ints = fn [cc(c)] (x: Rect, y: Rect) void
|
|
||||||
{
|
|
||||||
require(x.left == 1);
|
|
||||||
require(x.right == 21);
|
|
||||||
require(x.top == 16);
|
|
||||||
require(x.bottom == 4);
|
|
||||||
require(y.left == 178);
|
|
||||||
require(y.right == 189);
|
|
||||||
require(y.top == 21);
|
|
||||||
require(y.bottom == 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_small_struct_ints = fn [cc(c)] (x: SmallStructInts) void
|
|
||||||
{
|
|
||||||
require(x.a == 1);
|
|
||||||
require(x.b == 2);
|
|
||||||
require(x.c == 3);
|
|
||||||
require(x.d == 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] bb_med_struct_ints = fn [cc(c)] (s: MedStructInts) void
|
|
||||||
{
|
|
||||||
require(s.x == 1);
|
|
||||||
require(s.y == 2);
|
|
||||||
require(s.z == 3);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c_u8 = fn [cc(c)] (x: u8) void
|
|
||||||
{
|
|
||||||
require(x == 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>v: u8 = 0xff;
|
|
||||||
c_u8(v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
require = fn(ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c_u16 = fn [cc(c)] (v: u16) void
|
|
||||||
{
|
|
||||||
require(v == 0xfffe);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
c_u16(0xfffe);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
[extern] exit = fn [cc(c)] (exit_code: s32) noreturn;
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>c_function_pointer = &exit;
|
|
||||||
c_function_pointer(0);
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MedStructInts = struct
|
|
||||||
{
|
|
||||||
x: s32,
|
|
||||||
y: s32,
|
|
||||||
z: s32,
|
|
||||||
}
|
|
||||||
|
|
||||||
bb_ret_med_struct_ints = fn [cc(c)] () MedStructInts
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.x = 1,
|
|
||||||
.y = 2,
|
|
||||||
.z = 3,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
c_med_struct_ints = fn [cc(c)] (s: MedStructInts) void
|
|
||||||
{
|
|
||||||
require(s.x == 1);
|
|
||||||
require(s.y == 2);
|
|
||||||
require(s.z == 3);
|
|
||||||
|
|
||||||
>s2 = bb_ret_med_struct_ints();
|
|
||||||
|
|
||||||
require(s2.x == 1);
|
|
||||||
require(s2.y == 2);
|
|
||||||
require(s2.z == 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>med: MedStructInts = {
|
|
||||||
.x = 1,
|
|
||||||
.y = 2,
|
|
||||||
.z = 3,
|
|
||||||
};
|
|
||||||
c_med_struct_ints(med);
|
|
||||||
>med2 = bb_ret_med_struct_ints();
|
|
||||||
require(med2.x == 1);
|
|
||||||
require(med2.y == 2);
|
|
||||||
require(med2.z == 3);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
StructWithArray = struct
|
|
||||||
{
|
|
||||||
a: u32,
|
|
||||||
padding: [4]u8,
|
|
||||||
c: u64,
|
|
||||||
};
|
|
||||||
|
|
||||||
c_ret_struct_with_array = fn [cc(c)] () StructWithArray
|
|
||||||
{
|
|
||||||
return { .a = 4, .padding = [ 0, 0, 0, 0 ], .c = 155 };
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn(ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>s = c_ret_struct_with_array();
|
|
||||||
require(s.a == 4);
|
|
||||||
require(s.c == 155);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
SplitStructInt = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u8,
|
|
||||||
c: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bb_split_struct_ints = fn [cc(c)] (x: SplitStructInt) void
|
|
||||||
{
|
|
||||||
require(x.a == 1234);
|
|
||||||
require(x.b == 100);
|
|
||||||
require(x.c == 1337);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>split: SplitStructInt = {
|
|
||||||
.a = 1234,
|
|
||||||
.b = 100,
|
|
||||||
.c = 1337,
|
|
||||||
};
|
|
||||||
|
|
||||||
bb_split_struct_ints(split);
|
|
||||||
>a: s32 = #truncate(split.a);
|
|
||||||
>b: s32 = #extend(split.b);
|
|
||||||
>c: s32 = #extend(split.c);
|
|
||||||
return a + b + 3 - c;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c_string_length = fn (c_string: &u8) u64
|
|
||||||
{
|
|
||||||
>it = c_string;
|
|
||||||
|
|
||||||
while (it.&)
|
|
||||||
{
|
|
||||||
it = it + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return #int_from_pointer(it) - #int_from_pointer(c_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
c_string_slice_build = fn (c_string: &u8, length: u64) []u8
|
|
||||||
{
|
|
||||||
return c_string[0..length];
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32, argument_pointer: &&u8) s32
|
|
||||||
{
|
|
||||||
>length = c_string_length(argument_pointer[0]);
|
|
||||||
>string = c_string_slice_build(argument_pointer[0], length);
|
|
||||||
require(string.pointer == argument_pointer[0]);
|
|
||||||
require(string.length == length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
require = fn(ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StructWithArray = struct
|
|
||||||
{
|
|
||||||
a: u32,
|
|
||||||
padding: [4]u8,
|
|
||||||
b: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
c_struct_with_array = fn [cc(c)] (x: StructWithArray) void
|
|
||||||
{
|
|
||||||
require(x.a == 1);
|
|
||||||
require(x.b == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
c_struct_with_array({ .a = 1, .padding = [0, 0, 0, 0], .b = 2 });
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32 // This is a comment
|
|
||||||
// This is a comment
|
|
||||||
{ // This is a comment
|
|
||||||
// This is a comment
|
|
||||||
return 0; // This is a comment
|
|
||||||
}// This is a comment
|
|
||||||
// This is a comment
|
|
@ -1,14 +0,0 @@
|
|||||||
trivial_comparison = fn (a: u32, b: u32) u1
|
|
||||||
{
|
|
||||||
return a + 1 == b + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32) s32
|
|
||||||
{
|
|
||||||
>result = trivial_comparison(argument_count, argument_count);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
is_space = fn (ch: u8) u1
|
|
||||||
{
|
|
||||||
return ch == ' ' or ch == '\n' or ch == '\t' or ch == '\r';
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return #extend(is_space('f'));
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return -1 + 1;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 1 & 2;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 0 / 5;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
i2315_abc: s32 = 5;
|
|
||||||
asjdkj = i2315_abc - i2315_abc;
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return asjdkj;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 1 * 0;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 0 | 0;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 5 % 5;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 0 << 1;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 0 >> 1;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 1 - 1;
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 0 ^ 0;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0;
|
|
||||||
if (result == 1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (result == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
Foo = enum
|
|
||||||
{
|
|
||||||
a,b,c,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32) s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0;
|
|
||||||
>foo: Foo = .b;
|
|
||||||
switch (foo)
|
|
||||||
{
|
|
||||||
.b =>
|
|
||||||
{
|
|
||||||
if (argument_count != 0)
|
|
||||||
{
|
|
||||||
>a: s32 = 1;
|
|
||||||
if (result == 1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (result == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else =>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] (argument_count: u32) s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0;
|
|
||||||
if (argument_count != 1)
|
|
||||||
{
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
SomeEnum = enum
|
|
||||||
{
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
c,
|
|
||||||
d,
|
|
||||||
}
|
|
||||||
|
|
||||||
foo = fn (arg: SomeEnum) SomeEnum
|
|
||||||
{
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>some_e: SomeEnum = .c;
|
|
||||||
>a = foo(some_e);
|
|
||||||
>b = foo(.d);
|
|
||||||
if (a != .c) #trap();
|
|
||||||
if (b != .d) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok) #trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
E = enum
|
|
||||||
{
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
c,
|
|
||||||
d,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>some_enum_array: enum_array[E](u32) = [ .a = 4, .b = 3, .c = 2, .d = 1 ];
|
|
||||||
require(some_enum_array[.a] == 4);
|
|
||||||
require(some_enum_array[.b] == 3);
|
|
||||||
require(some_enum_array[.c] == 2);
|
|
||||||
require(some_enum_array[.d] == 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
TypeId = enum
|
|
||||||
{
|
|
||||||
void,
|
|
||||||
noreturn,
|
|
||||||
forward_declaration,
|
|
||||||
integer,
|
|
||||||
function,
|
|
||||||
pointer,
|
|
||||||
array,
|
|
||||||
enum,
|
|
||||||
struct,
|
|
||||||
bits,
|
|
||||||
alias,
|
|
||||||
union,
|
|
||||||
unresolved,
|
|
||||||
vector,
|
|
||||||
floating_point,
|
|
||||||
enum_array,
|
|
||||||
opaque,
|
|
||||||
}
|
|
||||||
|
|
||||||
Type = struct
|
|
||||||
{
|
|
||||||
arr: [5]u32,
|
|
||||||
id: TypeId,
|
|
||||||
a: [2]u64,
|
|
||||||
b: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>t: Type = {
|
|
||||||
.id = .integer,
|
|
||||||
zero,
|
|
||||||
};
|
|
||||||
t.arr[0] = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
E = enum
|
|
||||||
{
|
|
||||||
my_expected_result,
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
}
|
|
||||||
|
|
||||||
[extern] memcmp = fn [cc(c)] (a: &u8, b: &u8, byte_count: u64) s32;
|
|
||||||
string_equal = fn (slice_a: []u8, slice_b: []u8) u1
|
|
||||||
{
|
|
||||||
>result = slice_a.length == slice_b.length;
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
result = memcmp(slice_a.pointer, slice_b.pointer, slice_a.length) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>some_enum: E = .my_expected_result;
|
|
||||||
return #extend(!string_equal(#enum_name(some_enum), "my_expected_result"));
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s8 = 0;
|
|
||||||
return #extend(result);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[extern] exit = fn [cc(c)] (exit_code: s32) noreturn;
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
exit(0);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
S = struct
|
|
||||||
{
|
|
||||||
a: u32,
|
|
||||||
b: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok) #trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>s: S = {
|
|
||||||
.a = 2,
|
|
||||||
.b = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
s.a = s.b + 1;
|
|
||||||
s.b = s.a + 2;
|
|
||||||
require(s.a == 4);
|
|
||||||
require(s.b == 6);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
S = struct
|
|
||||||
{
|
|
||||||
a: u8,
|
|
||||||
b: u32,
|
|
||||||
c: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok) #trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>s: S = {
|
|
||||||
.a = 241,
|
|
||||||
.b = 12356,
|
|
||||||
.c = 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
>p_a = &s.a;
|
|
||||||
>p_a_struct: &S = #field_parent_pointer(p_a, "a");
|
|
||||||
assert(p_a_struct == &s);
|
|
||||||
assert(p_a_struct.a == s.a);
|
|
||||||
assert(p_a_struct.b == s.b);
|
|
||||||
assert(p_a_struct.c == s.c);
|
|
||||||
|
|
||||||
>p_b = &s.b;
|
|
||||||
>p_b_struct: &S = #field_parent_pointer(p_b, "b");
|
|
||||||
assert(p_b_struct == &s);
|
|
||||||
assert(p_b_struct.a == s.a);
|
|
||||||
assert(p_b_struct.b == s.b);
|
|
||||||
assert(p_b_struct.c == s.c);
|
|
||||||
|
|
||||||
>p_c = &s.c;
|
|
||||||
>p_c_struct: &S = #field_parent_pointer(p_c, "c");
|
|
||||||
assert(p_c_struct == &s);
|
|
||||||
assert(p_c_struct.a == s.a);
|
|
||||||
assert(p_c_struct.b == s.b);
|
|
||||||
assert(p_c_struct.c == s.c);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok) #trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>array: [_]u32 = [5, 3, 2];
|
|
||||||
>counter: u32 = 0;
|
|
||||||
for (e : array)
|
|
||||||
{
|
|
||||||
counter += e;
|
|
||||||
}
|
|
||||||
|
|
||||||
require(counter == 10);
|
|
||||||
|
|
||||||
for (&e : array)
|
|
||||||
{
|
|
||||||
e.& += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>new_counter: u32 = 0;
|
|
||||||
|
|
||||||
for (e : array)
|
|
||||||
{
|
|
||||||
new_counter += e;
|
|
||||||
}
|
|
||||||
|
|
||||||
require(new_counter == counter + array.length);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>top: s32 = 64;
|
|
||||||
>accumulator: s32 = 0;
|
|
||||||
for (i: 0..top)
|
|
||||||
{
|
|
||||||
accumulator += 1;
|
|
||||||
}
|
|
||||||
return accumulator - top;
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
T = struct;
|
|
||||||
Foo = struct
|
|
||||||
{
|
|
||||||
t: &T,
|
|
||||||
}
|
|
||||||
|
|
||||||
T = struct
|
|
||||||
{
|
|
||||||
f: Foo,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>t: T = zero;
|
|
||||||
t.f.t = &t;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
foo = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 123;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>fn_ptr = &foo;
|
|
||||||
return fn_ptr() - 123;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
sub = macro [T] (a: T, b: T) T
|
|
||||||
{
|
|
||||||
return a - b;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a = sub[s32](1, 1);
|
|
||||||
>b = sub[u8](2, 2);
|
|
||||||
return a + #extend(b);
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
foo = macro[T](addr: &u64, count: u64) []T
|
|
||||||
{
|
|
||||||
>pointer: &T = #pointer_cast(addr);
|
|
||||||
return pointer[..count];
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>address_raw: u64 = 0xaaaaaaaaaaaaaaaa;
|
|
||||||
>some_var: &u64 = #pointer_from_int(address_raw);
|
|
||||||
>result: []&u8 = foo[&u8](some_var, 1);
|
|
||||||
if (#int_from_pointer(result.pointer) != address_raw) #trap();
|
|
||||||
if (result.length != 1) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
foo = macro [T] (ptr: &u32) &T
|
|
||||||
{
|
|
||||||
return #pointer_cast(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
A = struct
|
|
||||||
{
|
|
||||||
a: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
B = struct
|
|
||||||
{
|
|
||||||
b: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>var: u32 = 0;
|
|
||||||
>a = foo[A](&var);
|
|
||||||
>b = foo[B](&var);
|
|
||||||
a.a = 1;
|
|
||||||
if (b.b != 1) #trap();
|
|
||||||
if (var != 1) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
result: s32 = 0;
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32 {
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
S = struct
|
|
||||||
{
|
|
||||||
a: u32,
|
|
||||||
b: u32,
|
|
||||||
c: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
s: S = {
|
|
||||||
.a = 1,
|
|
||||||
.b = 2,
|
|
||||||
.c = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn () s32
|
|
||||||
{
|
|
||||||
require(s.a == 1);
|
|
||||||
require(s.b == 2);
|
|
||||||
require(s.c == 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 5;
|
|
||||||
if (a == 2)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
require = fn [cc(c)] (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0;
|
|
||||||
require(result == 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
S = struct
|
|
||||||
{
|
|
||||||
a: u32,
|
|
||||||
b: u32,
|
|
||||||
c: u32,
|
|
||||||
d: u32,
|
|
||||||
e: u32,
|
|
||||||
f: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fn [cc(c)] () S
|
|
||||||
{
|
|
||||||
return { .a = 56, .b = 57, .c = 58, .d = 59, .e = 60, .f = 61 };
|
|
||||||
}
|
|
||||||
|
|
||||||
arg = fn [cc(c)] (s: S) void
|
|
||||||
{
|
|
||||||
require(s.a == 56);
|
|
||||||
require(s.b == 57);
|
|
||||||
require(s.c == 58);
|
|
||||||
require(s.d == 59);
|
|
||||||
require(s.e == 60);
|
|
||||||
require(s.f == 61);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>s = ret();
|
|
||||||
require(s.a == 56);
|
|
||||||
require(s.b == 57);
|
|
||||||
require(s.c == 58);
|
|
||||||
require(s.d == 59);
|
|
||||||
require(s.e == 60);
|
|
||||||
require(s.f == 61);
|
|
||||||
arg(s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
Struct_u64_u64 = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c_struct_u64_u64_5 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 33);
|
|
||||||
require(s.b == 34);
|
|
||||||
}
|
|
||||||
|
|
||||||
c_struct_u64_u64_6 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 35);
|
|
||||||
require(s.b == 36);
|
|
||||||
}
|
|
||||||
|
|
||||||
c_struct_u64_u64_7 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 37);
|
|
||||||
require(s.b == 38);
|
|
||||||
}
|
|
||||||
|
|
||||||
c_struct_u64_u64_8 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: u64, s: Struct_u64_u64) void
|
|
||||||
{
|
|
||||||
require(s.a == 39);
|
|
||||||
require(s.b == 40);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
c_struct_u64_u64_5(0, 0, 0, 0, 0, { .a = 33, .b = 34, });
|
|
||||||
c_struct_u64_u64_6(0, 0, 0, 0, 0, 0, { .a = 35, .b = 36, });
|
|
||||||
c_struct_u64_u64_7(0, 0, 0, 0, 0, 0, 0, { .a = 37, .b = 38, });
|
|
||||||
c_struct_u64_u64_8(0, 0, 0, 0, 0, 0, 0, 0, { .a = 39, .b = 40, });
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
S = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u64,
|
|
||||||
c: u64,
|
|
||||||
d: u64,
|
|
||||||
e: u64
|
|
||||||
f: u64,
|
|
||||||
g: u64,
|
|
||||||
h: u64,
|
|
||||||
i: u64,
|
|
||||||
j: u64
|
|
||||||
}
|
|
||||||
|
|
||||||
require = fn (ok: u1) void
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
va_arg_fn = fn [cc(c)] (first_arg: u32, ...) void
|
|
||||||
{
|
|
||||||
if (first_arg != 123456789)
|
|
||||||
{
|
|
||||||
#trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
>va = #va_start();
|
|
||||||
|
|
||||||
>s = #va_arg(&va, S);
|
|
||||||
require(s.a == 9);
|
|
||||||
require(s.b == 8);
|
|
||||||
require(s.c == 7);
|
|
||||||
require(s.d == 6);
|
|
||||||
require(s.e == 5);
|
|
||||||
require(s.f == 4);
|
|
||||||
require(s.g == 3);
|
|
||||||
require(s.h == 2);
|
|
||||||
require(s.i == 1);
|
|
||||||
require(s.j == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>first_arg: u32 = 123456789;
|
|
||||||
>s : S = {
|
|
||||||
.a = 9,
|
|
||||||
.b = 8,
|
|
||||||
.c = 7,
|
|
||||||
.d = 6,
|
|
||||||
.e = 5,
|
|
||||||
.f = 4,
|
|
||||||
.g = 3,
|
|
||||||
.h = 2,
|
|
||||||
.i = 1,
|
|
||||||
.j = 0,
|
|
||||||
};
|
|
||||||
va_arg_fn(first_arg, s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0o10;
|
|
||||||
>b: s32 = 0b1000;
|
|
||||||
>c: s32 = 0d0;
|
|
||||||
return a - b + c;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0x0;
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a = #integer_max(u64);
|
|
||||||
return #truncate(a + 1);
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: u32 = 0b111;
|
|
||||||
if (#leading_zeroes(a) != 29) #trap();
|
|
||||||
if (#trailing_zeroes(a) != 0) #trap();
|
|
||||||
>b: u8 = 0b11010;
|
|
||||||
if (#leading_zeroes(b) != 3) #trap();
|
|
||||||
if (#trailing_zeroes(b) != 1) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
foo = fn() s32
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
>result = foo() + a;
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: u32 = 1;
|
|
||||||
>b: u32 = 2;
|
|
||||||
>min = #min(a, b);
|
|
||||||
>max = #max(a, b);
|
|
||||||
if (min != a) #trap();
|
|
||||||
if (max != b) #trap();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: s32 = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 1;
|
|
||||||
return a - 1;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 1;
|
|
||||||
>b = a - 1;
|
|
||||||
return b;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user