Compare commits
No commits in common. "main" and "dev" have entirely different histories.
@ -1,30 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "**"
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- zig
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *"
|
|
||||||
|
|
||||||
env:
|
|
||||||
BB_CI: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
ci:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ ubuntu-latest ]
|
|
||||||
BIRTH_ZIG_BUILD_TYPE: [ Debug, ReleaseSafe, ReleaseFast, ReleaseSmall ]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Build and test (Packaged LLVM)
|
|
||||||
run: |
|
|
||||||
~/zig-linux-x86_64-0.14.0/zig build test -Doptimize=${{matrix.BIRTH_ZIG_BUILD_TYPE}} -Dsystem_llvm=false
|
|
||||||
ldd zig-out/bin/bloat-buster
|
|
77
.github/workflows/ci.yml
vendored
Normal file
77
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "**"
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- zig
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
env:
|
||||||
|
BB_CI: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate-config:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions: write-all
|
||||||
|
outputs:
|
||||||
|
BIRTH_GITHUB_TARGETS: ${{ steps.generate-config.outputs.BIRTH_GITHUB_TARGETS }}
|
||||||
|
BIRTH_BUILD_TYPES: ${{ steps.generate-config.outputs.BIRTH_BUILD_TYPES }}
|
||||||
|
BIRTH_CMAKE_BUILD_TYPES: ${{ steps.generate-config.outputs.BIRTH_CMAKE_BUILD_TYPES }}
|
||||||
|
BIRTH_COMPILERS: ${{ steps.generate-config.outputs.BIRTH_COMPILERS }}
|
||||||
|
BIRTH_LINUX_IMAGE: ${{ steps.generate-config.outputs.BIRTH_LINUX_IMAGE }}
|
||||||
|
BIRTH_MACOS_IMAGE: ${{ steps.generate-config.outputs.BIRTH_MACOS_IMAGE }}
|
||||||
|
BIRTH_WINDOWS_IMAGE: ${{ steps.generate-config.outputs.BIRTH_WINDOWS_IMAGE }}
|
||||||
|
RELEASE_TAG_NAME: ${{ steps.generate-tag.outputs.RELEASE_TAG_NAME }} # Define job output here
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Generate config
|
||||||
|
id: generate-config
|
||||||
|
uses: birth-software/github-config@v4
|
||||||
|
- name: Create tag
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
shell: bash
|
||||||
|
id: generate-tag
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
set -eux
|
||||||
|
git config --global user.name "github-actions"
|
||||||
|
git config --global user.email "github-actions@github.com"
|
||||||
|
TAG="dev"
|
||||||
|
gh release delete $TAG --yes || true
|
||||||
|
git tag -d $TAG || true
|
||||||
|
git push origin --delete $TAG || true
|
||||||
|
git fetch --tags
|
||||||
|
git tag -l
|
||||||
|
git tag $TAG
|
||||||
|
git push origin $TAG
|
||||||
|
echo "RELEASE_TAG_NAME=$TAG" >> $GITHUB_OUTPUT
|
||||||
|
ci:
|
||||||
|
needs: generate-config
|
||||||
|
permissions: write-all
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ x86_64-linux-znver4 ]
|
||||||
|
BIRTH_BUILD_TYPE: ${{ fromJSON(needs.generate-config.outputs.BIRTH_BUILD_TYPES) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
BIRTH_LINUX_IMAGE: ${{ needs.generate-config.outputs.BIRTH_LINUX_IMAGE }}
|
||||||
|
BIRTH_MACOS_IMAGE: ${{ needs.generate-config.outputs.BIRTH_MACOS_IMAGE }}
|
||||||
|
BIRTH_WINDOWS_IMAGE: ${{ needs.generate-config.outputs.BIRTH_WINDOWS_IMAGE }}
|
||||||
|
RELEASE_TAG_NAME: ${{ needs.generate-config.outputs.RELEASE_TAG_NAME }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build
|
||||||
|
env:
|
||||||
|
CC: clang
|
||||||
|
BB_BUILD_TYPE: ${{matrix.BIRTH_BUILD_TYPE}}
|
||||||
|
run: ./build.sh
|
||||||
|
- name: Run
|
||||||
|
run: ./cache/bb
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,4 +12,3 @@ imgui.ini
|
|||||||
/.gdb_history
|
/.gdb_history
|
||||||
/.zig-cache/
|
/.zig-cache/
|
||||||
/zig-out/
|
/zig-out/
|
||||||
/bb-cache/
|
|
||||||
|
363
build.zig
363
build.zig
@ -1,363 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const builtin = @import("builtin");
|
|
||||||
|
|
||||||
fn run_process_and_capture_stdout(b: *std.Build, argv: []const []const u8) ![]const u8 {
|
|
||||||
const result = std.process.Child.run(.{
|
|
||||||
.allocator = b.allocator,
|
|
||||||
.argv = argv,
|
|
||||||
}) catch |err| return err;
|
|
||||||
switch (result.term) {
|
|
||||||
.Exited => |exit_code| {
|
|
||||||
if (exit_code != 0) {
|
|
||||||
return error.SpawnError;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => return error.SpawnError,
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.stdout;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_find_in_path(allocator: std.mem.Allocator, file_name: []const u8, path_env: []const u8, extension: []const u8) ?[]const u8 {
|
|
||||||
const path_env_separator = switch (builtin.os.tag) {
|
|
||||||
.windows => ';',
|
|
||||||
else => ':',
|
|
||||||
};
|
|
||||||
const path_separator = switch (builtin.os.tag) {
|
|
||||||
.windows => '\\',
|
|
||||||
else => '/',
|
|
||||||
};
|
|
||||||
var env_it = std.mem.splitScalar(u8, path_env, path_env_separator);
|
|
||||||
const result: ?[]const u8 = while (env_it.next()) |dir_path| {
|
|
||||||
const full_path = std.mem.concatWithSentinel(allocator, u8, &.{ dir_path, &[1]u8{path_separator}, file_name, extension }, 0) catch unreachable;
|
|
||||||
const file = std.fs.cwd().openFile(full_path, .{}) catch continue;
|
|
||||||
file.close();
|
|
||||||
break full_path;
|
|
||||||
} else null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn executable_find_in_path(allocator: std.mem.Allocator, file_name: []const u8, path_env: []const u8) ?[]const u8 {
|
|
||||||
const extension = switch (builtin.os.tag) {
|
|
||||||
.windows => ".exe",
|
|
||||||
else => "",
|
|
||||||
};
|
|
||||||
return file_find_in_path(allocator, file_name, path_env, extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CmakeBuildType = enum {
|
|
||||||
Debug,
|
|
||||||
RelWithDebInfo,
|
|
||||||
MinSizeRel,
|
|
||||||
Release,
|
|
||||||
|
|
||||||
fn from_zig_build_type(o: std.builtin.OptimizeMode) CmakeBuildType {
|
|
||||||
return switch (o) {
|
|
||||||
.Debug => .Debug,
|
|
||||||
.ReleaseSafe => .RelWithDebInfo,
|
|
||||||
.ReleaseSmall => .MinSizeRel,
|
|
||||||
.ReleaseFast => .Release,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var system_llvm: bool = undefined;
|
|
||||||
var target: std.Build.ResolvedTarget = undefined;
|
|
||||||
var optimize: std.builtin.OptimizeMode = undefined;
|
|
||||||
var env: std.process.EnvMap = undefined;
|
|
||||||
|
|
||||||
const BuildMode = enum {
|
|
||||||
debug_none,
|
|
||||||
debug_fast,
|
|
||||||
debug_size,
|
|
||||||
soft_optimize,
|
|
||||||
optimize_for_speed,
|
|
||||||
optimize_for_size,
|
|
||||||
aggressively_optimize_for_speed,
|
|
||||||
aggressively_optimize_for_size,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
|
||||||
env = try std.process.getEnvMap(b.allocator);
|
|
||||||
target = b.standardTargetOptions(.{});
|
|
||||||
optimize = b.standardOptimizeOption(.{});
|
|
||||||
system_llvm = b.option(bool, "system_llvm", "Link against system LLVM libraries") orelse false;
|
|
||||||
|
|
||||||
const c_abi = b.addObject(.{
|
|
||||||
.name = "c_abi",
|
|
||||||
.link_libc = true,
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
.sanitize_c = false,
|
|
||||||
}),
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
c_abi.addCSourceFiles(.{
|
|
||||||
.files = &.{"tests/c_abi.c"},
|
|
||||||
.flags = &.{"-g"},
|
|
||||||
});
|
|
||||||
|
|
||||||
const path = env.get("PATH") orelse unreachable;
|
|
||||||
|
|
||||||
const stack_trace_library = b.addObject(.{
|
|
||||||
.name = "stack_trace",
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = .ReleaseFast,
|
|
||||||
.root_source_file = b.path("src/stack_trace.zig"),
|
|
||||||
.link_libc = true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const exe_mod = b.createModule(.{
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
.sanitize_c = false,
|
|
||||||
});
|
|
||||||
const configuration = b.addOptions();
|
|
||||||
configuration.addOptionPath("c_abi_object_path", c_abi.getEmittedBin());
|
|
||||||
exe_mod.addOptions("configuration", configuration);
|
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
|
||||||
.name = "bloat-buster",
|
|
||||||
.root_module = exe_mod,
|
|
||||||
.link_libc = true,
|
|
||||||
});
|
|
||||||
exe.addObject(stack_trace_library);
|
|
||||||
var llvm_libs = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
const llvm_config_path = if (b.option([]const u8, "llvm_prefix", "LLVM prefix")) |llvm_prefix| blk: {
|
|
||||||
const full_path = try std.mem.concat(b.allocator, u8, &.{ llvm_prefix, "/bin/llvm-config" });
|
|
||||||
const f = std.fs.cwd().openFile(full_path, .{}) catch return error.llvm_not_found;
|
|
||||||
f.close();
|
|
||||||
break :blk full_path;
|
|
||||||
} else if (system_llvm) executable_find_in_path(b.allocator, "llvm-config", path) orelse return error.llvm_not_found else blk: {
|
|
||||||
const home_env = switch (@import("builtin").os.tag) {
|
|
||||||
.windows => "USERPROFILE",
|
|
||||||
else => "HOME",
|
|
||||||
};
|
|
||||||
const home_path = env.get(home_env) orelse unreachable;
|
|
||||||
const is_ci = std.mem.eql(u8, (env.get("BB_CI") orelse "0"), "1");
|
|
||||||
const download_dir = try std.mem.concat(b.allocator, u8, &.{ home_path, "/Downloads" });
|
|
||||||
std.fs.makeDirAbsolute(download_dir) catch {};
|
|
||||||
const cmake_build_type = if (is_ci) CmakeBuildType.from_zig_build_type(optimize) else CmakeBuildType.Release;
|
|
||||||
const version_string = "20.1.2";
|
|
||||||
const llvm_base = try std.mem.concat(b.allocator, u8, &.{ "llvm_", version_string, "_", @tagName(target.result.cpu.arch), "-", @tagName(target.result.os.tag), "-", @tagName(cmake_build_type) });
|
|
||||||
const base = try std.mem.concat(b.allocator, u8, &.{ download_dir, "/", llvm_base });
|
|
||||||
const full_path = try std.mem.concat(b.allocator, u8, &.{ base, "/bin/llvm-config" });
|
|
||||||
|
|
||||||
const f = std.fs.cwd().openFile(full_path, .{}) catch {
|
|
||||||
const url = try std.mem.concat(b.allocator, u8, &.{ "https://github.com/birth-software/llvm/releases/download/v", version_string, "/", llvm_base, ".7z" });
|
|
||||||
var result = try std.process.Child.run(.{
|
|
||||||
.allocator = b.allocator,
|
|
||||||
.argv = &.{ "wget", "-P", download_dir, url },
|
|
||||||
.max_output_bytes = std.math.maxInt(usize),
|
|
||||||
});
|
|
||||||
var success = false;
|
|
||||||
switch (result.term) {
|
|
||||||
.Exited => |exit_code| {
|
|
||||||
success = exit_code == 0;
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
std.debug.print("{s}\n{s}\n", .{ result.stdout, result.stderr });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
const file_7z = try std.mem.concat(b.allocator, u8, &.{ base, ".7z" });
|
|
||||||
result = try std.process.Child.run(.{
|
|
||||||
.allocator = b.allocator,
|
|
||||||
.argv = &.{ "7z", "x", try std.mem.concat(b.allocator, u8, &.{ "-o", download_dir }), file_7z },
|
|
||||||
.max_output_bytes = std.math.maxInt(usize),
|
|
||||||
});
|
|
||||||
success = false;
|
|
||||||
switch (result.term) {
|
|
||||||
.Exited => |exit_code| {
|
|
||||||
success = exit_code == 0;
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
std.debug.print("{s}\n{s}\n", .{ result.stdout, result.stderr });
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk full_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return error.llvm_not_found;
|
|
||||||
};
|
|
||||||
|
|
||||||
f.close();
|
|
||||||
break :blk full_path;
|
|
||||||
};
|
|
||||||
const llvm_components_result = try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--components" });
|
|
||||||
var it = std.mem.splitScalar(u8, llvm_components_result, ' ');
|
|
||||||
{
|
|
||||||
var args = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
try args.append(llvm_config_path);
|
|
||||||
try args.append("--libs");
|
|
||||||
while (it.next()) |component| {
|
|
||||||
try args.append(std.mem.trimRight(u8, component, "\n"));
|
|
||||||
}
|
|
||||||
const llvm_libs_result = try run_process_and_capture_stdout(b, args.items);
|
|
||||||
it = std.mem.splitScalar(u8, llvm_libs_result, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
while (it.next()) |lib| {
|
|
||||||
const llvm_lib = std.mem.trimLeft(u8, std.mem.trimRight(u8, lib, "\n"), "-l");
|
|
||||||
try llvm_libs.append(llvm_lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm_cxx_flags_result = try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--cxxflags" });
|
|
||||||
it = std.mem.splitScalar(u8, llvm_cxx_flags_result, ' ');
|
|
||||||
while (it.next()) |flag| {
|
|
||||||
const llvm_cxx_flag = std.mem.trimRight(u8, flag, "\n");
|
|
||||||
try flags.append(llvm_cxx_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm_lib_dir = std.mem.trimRight(u8, try run_process_and_capture_stdout(b, &.{ llvm_config_path, "--libdir" }), "\n");
|
|
||||||
|
|
||||||
if (optimize != .ReleaseSmall) {
|
|
||||||
try flags.append("-g");
|
|
||||||
}
|
|
||||||
|
|
||||||
try flags.append("-fno-rtti");
|
|
||||||
|
|
||||||
exe.addLibraryPath(.{ .cwd_relative = llvm_lib_dir });
|
|
||||||
|
|
||||||
const a = std.fs.cwd().openDir("/usr/lib/x86_64-linux-gnu/", .{});
|
|
||||||
if (a) |_| {
|
|
||||||
var dir = a catch unreachable;
|
|
||||||
dir.close();
|
|
||||||
exe.addLibraryPath(.{ .cwd_relative = "/usr/lib/x86_64-linux-gnu/" });
|
|
||||||
} else |err| {
|
|
||||||
err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
exe.addCSourceFiles(.{
|
|
||||||
.files = &.{"src/llvm.cpp"},
|
|
||||||
.flags = flags.items,
|
|
||||||
});
|
|
||||||
|
|
||||||
var dir = try std.fs.cwd().openDir("/usr/include/c++", .{
|
|
||||||
.iterate = true,
|
|
||||||
});
|
|
||||||
var iterator = dir.iterate();
|
|
||||||
const gcc_version = while (try iterator.next()) |entry| {
|
|
||||||
if (entry.kind == .directory) {
|
|
||||||
break entry.name;
|
|
||||||
}
|
|
||||||
} else return error.include_cpp_dir_not_found;
|
|
||||||
dir.close();
|
|
||||||
const general_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ "/usr/include/c++/", gcc_version });
|
|
||||||
exe.addIncludePath(.{ .cwd_relative = general_cpp_include_dir });
|
|
||||||
|
|
||||||
{
|
|
||||||
const arch_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ general_cpp_include_dir, "/x86_64-pc-linux-gnu" });
|
|
||||||
const d2 = std.fs.cwd().openDir(arch_cpp_include_dir, .{});
|
|
||||||
if (d2) |_| {
|
|
||||||
var d = d2 catch unreachable;
|
|
||||||
d.close();
|
|
||||||
exe.addIncludePath(.{ .cwd_relative = arch_cpp_include_dir });
|
|
||||||
} else |err| err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const arch_cpp_include_dir = try std.mem.concat(b.allocator, u8, &.{ "/usr/include/x86_64-linux-gnu/c++/", gcc_version });
|
|
||||||
const d2 = std.fs.cwd().openDir(arch_cpp_include_dir, .{});
|
|
||||||
if (d2) |_| {
|
|
||||||
var d = d2 catch unreachable;
|
|
||||||
d.close();
|
|
||||||
exe.addIncludePath(.{ .cwd_relative = arch_cpp_include_dir });
|
|
||||||
} else |err| err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var found_libcpp = false;
|
|
||||||
|
|
||||||
if (std.fs.cwd().openFile("/usr/lib/libstdc++.so.6", .{})) |file| {
|
|
||||||
file.close();
|
|
||||||
found_libcpp = true;
|
|
||||||
exe.addObjectFile(.{ .cwd_relative = "/usr/lib/libstdc++.so.6" });
|
|
||||||
} else |err| {
|
|
||||||
err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std.fs.cwd().openFile("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", .{})) |file| {
|
|
||||||
file.close();
|
|
||||||
found_libcpp = true;
|
|
||||||
exe.addObjectFile(.{ .cwd_relative = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" });
|
|
||||||
} else |err| {
|
|
||||||
err catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_libcpp) {
|
|
||||||
return error.libcpp_not_found;
|
|
||||||
}
|
|
||||||
|
|
||||||
const needed_libraries: []const []const u8 = &.{ "unwind", "z", "zstd" };
|
|
||||||
for (needed_libraries) |lib| {
|
|
||||||
exe.linkSystemLibrary(lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (llvm_libs.items) |lib| {
|
|
||||||
exe.linkSystemLibrary(lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
const lld_libs: []const []const u8 = &.{ "lldCommon", "lldCOFF", "lldELF", "lldMachO", "lldMinGW", "lldWasm" };
|
|
||||||
for (lld_libs) |lib| {
|
|
||||||
exe.linkSystemLibrary(lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
b.installArtifact(exe);
|
|
||||||
|
|
||||||
for ([_]bool{ false, true }) |is_test| {
|
|
||||||
const run_step_name = switch (is_test) {
|
|
||||||
true => "test",
|
|
||||||
false => "run",
|
|
||||||
};
|
|
||||||
|
|
||||||
const debug_step_name = switch (is_test) {
|
|
||||||
true => "debug_test",
|
|
||||||
false => "debug",
|
|
||||||
};
|
|
||||||
|
|
||||||
const command = b.addRunArtifact(exe);
|
|
||||||
command.step.dependOn(b.getInstallStep());
|
|
||||||
|
|
||||||
if (is_test) {
|
|
||||||
command.addArg("test");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b.args) |args| {
|
|
||||||
command.addArgs(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
const run_step = b.step(run_step_name, "");
|
|
||||||
run_step.dependOn(&command.step);
|
|
||||||
|
|
||||||
const debug_command = std.Build.Step.Run.create(b, b.fmt("{s} {s}", .{ debug_step_name, exe.name }));
|
|
||||||
debug_command.addArg("gdb");
|
|
||||||
debug_command.addArg("-ex");
|
|
||||||
debug_command.addArg("r");
|
|
||||||
debug_command.addArg("--args");
|
|
||||||
debug_command.addArtifactArg(exe);
|
|
||||||
|
|
||||||
if (is_test) {
|
|
||||||
debug_command.addArg("test");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b.args) |args| {
|
|
||||||
debug_command.addArgs(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
const debug_step = b.step(debug_step_name, "");
|
|
||||||
debug_step.dependOn(&debug_command.step);
|
|
||||||
}
|
|
||||||
}
|
|
1886
src/LLVM.zig
1886
src/LLVM.zig
File diff suppressed because it is too large
Load Diff
8656
src/bootstrap.zig
8656
src/bootstrap.zig
File diff suppressed because it is too large
Load Diff
355
src/compiler.bbb
355
src/compiler.bbb
@ -1,355 +0,0 @@
|
|||||||
[extern] memcmp = fn [cc(c)] (a: &u8, b: &u8, byte_count: u64) s32;
|
|
||||||
|
|
||||||
string_no_match = #integer_max(u64);
|
|
||||||
|
|
||||||
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_to_slice = fn (c_string: &u8) []u8
|
|
||||||
{
|
|
||||||
>length = c_string_length(c_string);
|
|
||||||
return c_string[0..length];
|
|
||||||
}
|
|
||||||
|
|
||||||
string_equal = fn(a: []u8, b: []u8) u1
|
|
||||||
{
|
|
||||||
>result: #ReturnType = 0;
|
|
||||||
|
|
||||||
if (a.length == b.length)
|
|
||||||
{
|
|
||||||
result = memcmp(a.pointer, b.pointer, a.length) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
string_last_character = fn(string: []u8, character: u8) u64
|
|
||||||
{
|
|
||||||
>i = string.length;
|
|
||||||
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
i -= 1;
|
|
||||||
|
|
||||||
if (string[i] == character)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_no_match;
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_Linux_PROT = bits u32
|
|
||||||
{
|
|
||||||
read: u1,
|
|
||||||
write: u1,
|
|
||||||
execute: u1,
|
|
||||||
sem: u1,
|
|
||||||
_: u28,
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_Linux_MAP_Type = enum u4
|
|
||||||
{
|
|
||||||
shared = 0x1,
|
|
||||||
private = 0x2,
|
|
||||||
shared_validate = 0x3,
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_Linux_MAP = bits u32
|
|
||||||
{
|
|
||||||
type: OS_Linux_MAP_Type,
|
|
||||||
fixed: u1,
|
|
||||||
anonymous: u1,
|
|
||||||
bit_32: u1,
|
|
||||||
_: u1,
|
|
||||||
grows_down: u1,
|
|
||||||
_: u2,
|
|
||||||
deny_write: u1,
|
|
||||||
executable: u1,
|
|
||||||
locked: u1,
|
|
||||||
no_reserve: u1,
|
|
||||||
populate: u1,
|
|
||||||
non_block: u1,
|
|
||||||
stack: u1,
|
|
||||||
huge_tlb: u1,
|
|
||||||
sync: u1,
|
|
||||||
fixed_noreplace: u1,
|
|
||||||
_: u5,
|
|
||||||
uninitialized: u1,
|
|
||||||
_: u5,
|
|
||||||
}
|
|
||||||
|
|
||||||
[extern] mmap = fn [cc(c)] (address: u64, size: u64, protection: OS_Linux_PROT, map: OS_Linux_MAP, file_descriptor: s32, offset: s64) &u8;
|
|
||||||
[extern] mprotect = fn [cc(c)] (address: u64, size: u64, protection: OS_Linux_PROT) s32;
|
|
||||||
|
|
||||||
OS_ProtectionFlags = bits
|
|
||||||
{
|
|
||||||
read: u1,
|
|
||||||
write: u1,
|
|
||||||
execute: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_MapFlags = bits
|
|
||||||
{
|
|
||||||
private: u1,
|
|
||||||
anonymous: u1,
|
|
||||||
no_reserve: u1,
|
|
||||||
populate: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
os_linux_protection_flags = fn(map_flags: OS_ProtectionFlags) OS_Linux_PROT
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.read = map_flags.read,
|
|
||||||
.write = map_flags.write,
|
|
||||||
.execute = map_flags.execute,
|
|
||||||
zero,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
os_linux_map_flags = fn(map_flags: OS_MapFlags) OS_Linux_MAP
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.type = #select(map_flags.private, .private, .shared),
|
|
||||||
.anonymous = map_flags.anonymous,
|
|
||||||
.no_reserve = map_flags.no_reserve,
|
|
||||||
.populate = map_flags.populate,
|
|
||||||
zero,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
os_reserve = fn (base: u64, size: u64, protection: OS_ProtectionFlags, map: OS_MapFlags) &u8
|
|
||||||
{
|
|
||||||
>protection_flags = os_linux_protection_flags(protection);
|
|
||||||
>map_flags = os_linux_map_flags(map);
|
|
||||||
>address = mmap(base, size, protection_flags, map_flags, -1, 0);
|
|
||||||
if (#int_from_pointer(address) == #integer_max(u64))
|
|
||||||
{
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_commit = fn (address: u64, size: u64, protection: OS_ProtectionFlags) void
|
|
||||||
{
|
|
||||||
>protection_flags = os_linux_protection_flags(protection);
|
|
||||||
>result = mprotect(address, size, protection_flags);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Arena = struct
|
|
||||||
{
|
|
||||||
reserved_size: u64,
|
|
||||||
position: u64,
|
|
||||||
os_position: u64,
|
|
||||||
granularity: u64,
|
|
||||||
reserved: [32]u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
minimum_position: u64 = #byte_size(Arena);
|
|
||||||
|
|
||||||
ArenaInitialization = struct
|
|
||||||
{
|
|
||||||
reserved_size: u64,
|
|
||||||
granularity: u64,
|
|
||||||
initial_size: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
arena_initialize = fn (initialization: ArenaInitialization) &Arena
|
|
||||||
{
|
|
||||||
>protection_flags: OS_ProtectionFlags = {
|
|
||||||
.read = 1,
|
|
||||||
.write = 1,
|
|
||||||
zero,
|
|
||||||
};
|
|
||||||
|
|
||||||
>map_flags: OS_MapFlags = {
|
|
||||||
.private = 1,
|
|
||||||
.anonymous = 1,
|
|
||||||
.no_reserve = 1,
|
|
||||||
.populate = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
>arena: &Arena = #pointer_cast(os_reserve(0, initialization.reserved_size, protection_flags, map_flags));
|
|
||||||
os_commit(#int_from_pointer(arena), initialization.initial_size, {
|
|
||||||
.read = 1,
|
|
||||||
.write = 1,
|
|
||||||
zero,
|
|
||||||
});
|
|
||||||
|
|
||||||
arena.& = {
|
|
||||||
.reserved_size = initialization.reserved_size,
|
|
||||||
.position = minimum_position,
|
|
||||||
.os_position = initialization.initial_size,
|
|
||||||
.granularity = initialization.granularity,
|
|
||||||
zero,
|
|
||||||
};
|
|
||||||
|
|
||||||
return arena;
|
|
||||||
}
|
|
||||||
|
|
||||||
arena_initialize_default = fn (initial_size: u64) &Arena
|
|
||||||
{
|
|
||||||
return arena_initialize({
|
|
||||||
.reserved_size = 4 * 1024 * 1024 * 1024,
|
|
||||||
.granularity = 4 * 1024,
|
|
||||||
.initial_size = initial_size,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalState = struct
|
|
||||||
{
|
|
||||||
arena: &Arena,
|
|
||||||
}
|
|
||||||
|
|
||||||
global_state: GlobalState = undefined;
|
|
||||||
|
|
||||||
global_state_initialize = fn () void
|
|
||||||
{
|
|
||||||
global_state = {
|
|
||||||
.arena = arena_initialize_default(2 * 1024 * 1024),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
CompilerCommand = enum
|
|
||||||
{
|
|
||||||
compile,
|
|
||||||
test,
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildMode = enum
|
|
||||||
{
|
|
||||||
debug_none,
|
|
||||||
debug_fast,
|
|
||||||
debug_size,
|
|
||||||
soft_optimize,
|
|
||||||
optimize_for_speed,
|
|
||||||
optimize_for_size,
|
|
||||||
aggressively_optimize_for_speed,
|
|
||||||
aggressively_optimize_for_size,
|
|
||||||
}
|
|
||||||
|
|
||||||
CompileFile = struct
|
|
||||||
{
|
|
||||||
relative_file_path: []u8,
|
|
||||||
build_mode: BuildMode,
|
|
||||||
has_debug_info: u1,
|
|
||||||
silent: u1,
|
|
||||||
}
|
|
||||||
|
|
||||||
compile_file = fn (arena: &Arena, compile: CompileFile) void
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8) s32
|
|
||||||
{
|
|
||||||
global_state_initialize();
|
|
||||||
>arena = global_state.arena;
|
|
||||||
|
|
||||||
if (argument_count < 2)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>command_string = c_string_to_slice(argv[1]);
|
|
||||||
|
|
||||||
>command_string_to_enum = #string_to_enum(CompilerCommand, command_string);
|
|
||||||
if (!command_string_to_enum.is_valid)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>command = command_string_to_enum.enum_value;
|
|
||||||
switch (command)
|
|
||||||
{
|
|
||||||
.compile =>
|
|
||||||
{
|
|
||||||
if (argument_count < 3)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>build_mode: BuildMode = .debug_none;
|
|
||||||
>has_debug_info: u1 = 1;
|
|
||||||
|
|
||||||
if (argument_count >= 4)
|
|
||||||
{
|
|
||||||
>build_mode_string_to_enum = #string_to_enum(BuildMode, c_string_to_slice(argv[3]));
|
|
||||||
if (!build_mode_string_to_enum.is_valid)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
build_mode = build_mode_string_to_enum.enum_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argument_count >= 5)
|
|
||||||
{
|
|
||||||
>has_debug_info_string = c_string_to_slice(argv[4]);
|
|
||||||
if (string_equal(has_debug_info_string, "true"))
|
|
||||||
{
|
|
||||||
has_debug_info = 1;
|
|
||||||
}
|
|
||||||
else if (string_equal(has_debug_info_string, "false"))
|
|
||||||
{
|
|
||||||
has_debug_info = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
>relative_file_path_pointer = argv[2];
|
|
||||||
if (!relative_file_path_pointer)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>relative_file_path = c_string_to_slice(relative_file_path_pointer);
|
|
||||||
|
|
||||||
if (relative_file_path.length < 5)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
>extension_start = string_last_character(relative_file_path, '.');
|
|
||||||
if (extension_start == string_no_match)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string_equal(relative_file_path[extension_start..], ".bbb"))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
compile_file(arena, {
|
|
||||||
.relative_file_path = relative_file_path,
|
|
||||||
.build_mode = build_mode,
|
|
||||||
.has_debug_info = has_debug_info,
|
|
||||||
.silent = 0,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
.test =>
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
#trap();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
3151
src/lib.zig
3151
src/lib.zig
File diff suppressed because it is too large
Load Diff
1858
src/llvm.cpp
1858
src/llvm.cpp
File diff suppressed because it is too large
Load Diff
292
src/llvm_api.zig
292
src/llvm_api.zig
@ -1,292 +0,0 @@
|
|||||||
const llvm = @import("LLVM.zig");
|
|
||||||
const lld = llvm.lld;
|
|
||||||
|
|
||||||
const Bool = c_int;
|
|
||||||
|
|
||||||
pub extern fn llvm_context_create_module(context: *llvm.Context, name: llvm.String) *llvm.Module;
|
|
||||||
pub extern fn LLVMContextCreate() *llvm.Context;
|
|
||||||
pub extern fn LLVMCreateBuilderInContext(context: *llvm.Context) *llvm.Builder;
|
|
||||||
|
|
||||||
pub extern fn LLVMGetOperand(value: *llvm.Value, index: c_uint) *llvm.Value;
|
|
||||||
pub extern fn LLVMSetAlignment(value: *llvm.Value, alignment: c_uint) void;
|
|
||||||
pub extern fn llvm_instruction_is_call_base(instruction: *llvm.Instruction) bool;
|
|
||||||
|
|
||||||
// Module
|
|
||||||
pub extern fn llvm_module_create_global_variable(module: *llvm.Module, global_type: *llvm.Type, is_constant: bool, linkage: llvm.LinkageType, initial_value: *llvm.Constant, name: llvm.String, before: ?*llvm.GlobalVariable, thread_local_mode: llvm.ThreadLocalMode, address_space: c_uint, externally_initialized: bool) *llvm.GlobalVariable;
|
|
||||||
pub extern fn LLVMSetUnnamedAddress(global: *llvm.GlobalVariable, unnamed_address: llvm.GlobalVariable.UnnamedAddress) void;
|
|
||||||
pub extern fn llvm_module_create_function(module: *llvm.Module, function_type: *llvm.Type.Function, linkage_type: llvm.LinkageType, address_space: c_uint, name: llvm.String) *llvm.Function;
|
|
||||||
pub extern fn llvm_context_create_basic_block(context: *llvm.Context, name: llvm.String, parent: ?*llvm.Function) *llvm.BasicBlock;
|
|
||||||
pub extern fn LLVMGetNextBasicBlock(basic_block: *llvm.BasicBlock) ?*llvm.BasicBlock;
|
|
||||||
pub extern fn LLVMDeleteBasicBlock(basic_block: *llvm.BasicBlock) void;
|
|
||||||
pub extern fn LLVMGetLastBasicBlock(function: *llvm.Function) *llvm.BasicBlock;
|
|
||||||
pub extern fn LLVMGetBasicBlockParent(basic_block: *llvm.BasicBlock) ?*llvm.BasicBlock;
|
|
||||||
pub extern fn LLVMAppendExistingBasicBlock(function: *llvm.Function, basic_block: *llvm.BasicBlock) void;
|
|
||||||
pub extern fn LLVMInsertExistingBasicBlockAfterInsertBlock(builder: *llvm.Builder, basic_block: *llvm.BasicBlock) void;
|
|
||||||
|
|
||||||
pub extern fn LLVMSetValueName2(value: *llvm.Value, name_pointer: [*]const u8, name_length: usize) void;
|
|
||||||
pub extern fn llvm_value_use_empty(value: *llvm.Value) bool;
|
|
||||||
pub extern fn llvm_value_has_one_use(value: *llvm.Value) bool;
|
|
||||||
pub extern fn llvm_value_to_branch(value: ?*llvm.Value) ?*llvm.Instruction.Branch;
|
|
||||||
pub extern fn LLVMReplaceAllUsesWith(old: *llvm.Value, new: *llvm.Value) void;
|
|
||||||
|
|
||||||
pub extern fn LLVMGetSuccessor(branch: *llvm.Instruction.Branch, index: c_uint) *llvm.BasicBlock;
|
|
||||||
pub extern fn LLVMIsConditional(branch: *llvm.Instruction.Branch) bool;
|
|
||||||
pub extern fn LLVMGetInstructionParent(instruction: *llvm.Instruction) *llvm.BasicBlock;
|
|
||||||
|
|
||||||
pub extern fn llvm_basic_block_is_empty(basic_block: *llvm.BasicBlock) bool;
|
|
||||||
pub extern fn llvm_basic_block_user_begin(basic_block: *llvm.BasicBlock) ?*llvm.Value;
|
|
||||||
pub extern fn llvm_basic_block_delete(basic_block: *llvm.BasicBlock) void;
|
|
||||||
pub extern fn LLVMGetBasicBlockTerminator(basic_block: *llvm.BasicBlock) ?*llvm.Value;
|
|
||||||
|
|
||||||
pub extern fn LLVMSetFunctionCallConv(function: *llvm.Function, calling_convention: llvm.CallingConvention) void;
|
|
||||||
pub extern fn LLVMGetFunctionCallConv(function: *llvm.Function) llvm.CallingConvention;
|
|
||||||
|
|
||||||
pub extern fn LLVMSetInstructionCallConv(instruction: *llvm.Instruction.CallBase, calling_convention: llvm.CallingConvention) void;
|
|
||||||
|
|
||||||
pub extern fn LLVMGetParams(function: *llvm.Function, argument_buffer: [*]*llvm.Argument) void;
|
|
||||||
|
|
||||||
pub extern fn llvm_function_to_string(function: *llvm.Function) llvm.String;
|
|
||||||
pub extern fn llvm_function_verify(function: *llvm.Function, error_message: *llvm.String) bool;
|
|
||||||
pub extern fn llvm_module_verify(module: *llvm.Module, error_message: *llvm.String) bool;
|
|
||||||
|
|
||||||
pub extern fn llvm_module_to_string(module: *llvm.Module) llvm.String;
|
|
||||||
|
|
||||||
// Builder API
|
|
||||||
pub extern fn LLVMPositionBuilderAtEnd(builder: *llvm.Builder, basic_block: *llvm.BasicBlock) void;
|
|
||||||
pub extern fn LLVMClearInsertionPosition(builder: *llvm.Builder) void;
|
|
||||||
pub extern fn LLVMGetInsertBlock(builder: *llvm.Builder) ?*llvm.BasicBlock;
|
|
||||||
|
|
||||||
pub extern fn llvm_find_return_value_dominating_store(builder: *llvm.Builder, return_alloca: *llvm.Value, element_type: *llvm.Type) ?*llvm.Instruction.Store;
|
|
||||||
|
|
||||||
pub extern fn LLVMDeleteInstruction(instruction: *llvm.Instruction) void;
|
|
||||||
pub extern fn LLVMInstructionEraseFromParent(instruction: *llvm.Instruction) void;
|
|
||||||
|
|
||||||
pub extern fn LLVMBuildRet(builder: *llvm.Builder, value: ?*llvm.Value) void;
|
|
||||||
pub extern fn LLVMBuildAdd(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildSub(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildMul(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildSDiv(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildUDiv(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildSRem(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildURem(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildShl(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildAShr(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildLShr(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildAnd(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildOr(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildXor(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildICmp(builder: *llvm.Builder, predicate: llvm.IntPredicate, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildBr(builder: *llvm.Builder, block: *llvm.BasicBlock) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildCondBr(builder: *llvm.Builder, condition: *llvm.Value, taken: *llvm.BasicBlock, not_taken: *llvm.BasicBlock) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildNeg(builder: *llvm.Builder, value: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildNot(builder: *llvm.Builder, value: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
|
|
||||||
pub extern fn llvm_builder_create_alloca(builder: *llvm.Builder, ty: *llvm.Type, address_space: c_uint, name: llvm.String) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildStore(builder: *llvm.Builder, value: *llvm.Value, pointer: *llvm.Value) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildLoad2(builder: *llvm.Builder, ty: *llvm.Type, pointer: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildCall2(builder: *llvm.Builder, ty: *llvm.Type.Function, pointer: *llvm.Value, argument_pointer: [*]const *llvm.Value, argument_count: c_uint, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildStructGEP2(builder: *llvm.Builder, struct_type: *llvm.Type.Struct, pointer: *llvm.Value, index: c_uint, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildGEP2(builder: *llvm.Builder, ty: *llvm.Type, aggregate: *llvm.Value, index_pointer: [*]const *llvm.Value, index_count: c_uint, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildInBoundsGEP2(builder: *llvm.Builder, ty: *llvm.Type, aggregate: *llvm.Value, index_pointer: [*]const *llvm.Value, index_count: c_uint, name: [*:0]const u8) *llvm.Value;
|
|
||||||
|
|
||||||
pub extern fn LLVMBuildInsertValue(builder: *llvm.Builder, aggregate: *llvm.Value, element: *llvm.Value, index: c_uint, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildExtractValue(builder: *llvm.Builder, aggregate: *llvm.Value, index: c_uint, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildUnreachable(builder: *llvm.Builder) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildMemCpy(builder: *llvm.Builder, destination: *llvm.Value, destination_alignment: c_uint, source: *llvm.Value, source_alignment: c_uint, size: *llvm.Value) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildMemSet(builder: *llvm.Builder, pointer: *llvm.Value, value: *llvm.Value, value_count: *llvm.Value, alignment: c_uint) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildPhi(builder: *llvm.Builder, ty: *llvm.Type, name: [*:0]const u8) *llvm.Instruction.Phi;
|
|
||||||
pub extern fn LLVMAddIncoming(phi: *llvm.Instruction.Phi, incoming_value_pointer: [*]const *llvm.Value, incoming_basic_block_pointer: [*]const *llvm.BasicBlock, incoming_count: c_uint) void;
|
|
||||||
pub extern fn LLVMBuildSelect(builder: *llvm.Builder, condition: *llvm.Value, true_value: *llvm.Value, false_value: *llvm.Value, name: [*:0]const u8) *llvm.Value;
|
|
||||||
|
|
||||||
pub extern fn LLVMBuildVAArg(builder: *llvm.Builder, va_list: *llvm.Value, arg_type: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildSwitch(builder: *llvm.Builder, discriminant: *llvm.Value, else_basic_block: *llvm.BasicBlock, case_count: c_uint) *llvm.Instruction.Switch;
|
|
||||||
pub extern fn LLVMAddCase(switchi: *llvm.Instruction.Switch, case_value: *llvm.Value, case_block: *llvm.BasicBlock) void;
|
|
||||||
|
|
||||||
// Casts
|
|
||||||
pub extern fn LLVMBuildIntCast2(builder: *llvm.Builder, value: *llvm.Value, destination_type: *llvm.Type, is_signed: Bool, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildZExt(builder: *llvm.Builder, value: *llvm.Value, destination_type: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildSExt(builder: *llvm.Builder, value: *llvm.Value, destination_type: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildTrunc(builder: *llvm.Builder, value: *llvm.Value, destination_type: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildIntToPtr(builder: *llvm.Builder, value: *llvm.Value, destination_type: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildPtrToInt(builder: *llvm.Builder, value: *llvm.Value, destination_type: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
pub extern fn LLVMBuildPointerCast(builder: *llvm.Builder, value: *llvm.Value, ty: *llvm.Type, name: [*:0]const u8) *llvm.Value;
|
|
||||||
|
|
||||||
pub extern fn LLVMSetCurrentDebugLocation2(builder: *llvm.Builder, location: ?*llvm.DI.Location) void;
|
|
||||||
|
|
||||||
pub extern fn LLVMTypeOf(value: *llvm.Value) *llvm.Type;
|
|
||||||
pub extern fn LLVMSizeOf(ty: *llvm.Type) *llvm.Constant;
|
|
||||||
pub extern fn LLVMAlignOf(ty: *llvm.Type) *llvm.Constant;
|
|
||||||
pub extern fn LLVMGlobalGetValueType(value: *llvm.GlobalValue) *llvm.Type;
|
|
||||||
pub extern fn LLVMGetInitializer(global_variable: *llvm.GlobalVariable) *llvm.Constant;
|
|
||||||
pub extern fn LLVMSetInitializer(global_variable: *llvm.GlobalVariable, initializer: *llvm.Constant) void;
|
|
||||||
pub extern fn LLVMDeleteGlobal(global_variable: *llvm.GlobalVariable) void;
|
|
||||||
pub extern fn llvm_global_variable_delete(global_variable: *llvm.GlobalVariable) void;
|
|
||||||
pub extern fn llvm_value_is_instruction(value: *llvm.Value) bool;
|
|
||||||
|
|
||||||
// Intrinsics
|
|
||||||
pub extern fn LLVMLookupIntrinsicID(name_pointer: [*]const u8, name_length: usize) llvm.Intrinsic.Id;
|
|
||||||
pub extern fn LLVMGetNamedFunction(module: *llvm.Module, name: [*:0]const u8) *llvm.Function;
|
|
||||||
pub extern fn LLVMGetIntrinsicDeclaration(module: *llvm.Module, intrinsic_id: llvm.Intrinsic.Id, parameter_type_pointer: [*]const *llvm.Type, parameter_type_count: usize) *llvm.Value;
|
|
||||||
pub extern fn LLVMIntrinsicGetType(context: *llvm.Context, intrinsic_id: llvm.Intrinsic.Id, parameter_type_pointer: [*]const *llvm.Type, parameter_type_count: usize) *llvm.Type.Function;
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
pub extern fn llvm_attribute_list_build(context: *llvm.Context, options: *const llvm.Attribute.List.Options, call_site: bool) *llvm.Attribute.List;
|
|
||||||
pub extern fn llvm_function_set_attributes(function: *llvm.Function, attribute_list: *llvm.Attribute.List) void;
|
|
||||||
pub extern fn llvm_call_base_set_attributes(function: *llvm.Instruction.CallBase, attribute_list: *llvm.Attribute.List) void;
|
|
||||||
|
|
||||||
// pub extern fn LLVMGetEnumAttributeKindForName(name_pointer: [*]const u8, name_length: usize) llvm.Attribute.Kind;
|
|
||||||
//
|
|
||||||
// pub extern fn LLVMCreateEnumAttribute(context: *llvm.Context, kind: llvm.Attribute.Kind, value: u64) *llvm.Attribute;
|
|
||||||
// pub extern fn LLVMCreateTypeAttribute(context: *llvm.Context, kind: llvm.Attribute.Kind, ty: *llvm.Type) *llvm.Attribute;
|
|
||||||
// pub extern fn LLVMCreateConstantRangeAttribute(context: *llvm.Context, kind: llvm.Attribute.Kind, bit_count: c_uint, lower_words: [*]const u64, upper_words: [*]const u64) *llvm.Attribute;
|
|
||||||
// pub extern fn LLVMCreateStringAttribute(context: *llvm.Context, key_pointer: [*]const u8, key_length: c_uint, value_pointer: [*]const u8, value_length: usize) *llvm.Attribute;
|
|
||||||
//
|
|
||||||
// pub extern fn LLVMAddAttributeAtIndex(function: *llvm.Function, attribute_index: llvm.Attribute.Index, attribute: *llvm.Attribute) void;
|
|
||||||
// pub extern fn LLVMAddCallSiteAttribute(call: *llvm.Instruction.Call, attribute_index: llvm.Attribute.Index, attribute: *llvm.Attribute) void;
|
|
||||||
|
|
||||||
// TYPES
|
|
||||||
// Types: integers
|
|
||||||
pub extern fn LLVMVoidTypeInContext(context: *llvm.Context) *llvm.Type;
|
|
||||||
pub extern fn LLVMInt1TypeInContext(context: *llvm.Context) *llvm.Type.Integer;
|
|
||||||
pub extern fn LLVMInt8TypeInContext(context: *llvm.Context) *llvm.Type.Integer;
|
|
||||||
pub extern fn LLVMInt16TypeInContext(context: *llvm.Context) *llvm.Type.Integer;
|
|
||||||
pub extern fn LLVMInt32TypeInContext(context: *llvm.Context) *llvm.Type.Integer;
|
|
||||||
pub extern fn LLVMInt64TypeInContext(context: *llvm.Context) *llvm.Type.Integer;
|
|
||||||
pub extern fn LLVMInt128TypeInContext(context: *llvm.Context) *llvm.Type.Integer;
|
|
||||||
pub extern fn LLVMIntTypeInContext(context: *llvm.Context, bit_count: c_uint) *llvm.Type.Integer;
|
|
||||||
|
|
||||||
// Types: floating point
|
|
||||||
pub extern fn LLVMHalfTypeInContext(context: *llvm.Context) *llvm.Type;
|
|
||||||
pub extern fn LLVMBFloatTypeInContext(context: *llvm.Context) *llvm.Type;
|
|
||||||
pub extern fn LLVMFloatTypeInContext(context: *llvm.Context) *llvm.Type;
|
|
||||||
pub extern fn LLVMDoubleTypeInContext(context: *llvm.Context) *llvm.Type;
|
|
||||||
pub extern fn LLVMFP128TypeInContext(context: *llvm.Context) *llvm.Type;
|
|
||||||
|
|
||||||
// Types: functions
|
|
||||||
pub extern fn LLVMFunctionType(return_type: *llvm.Type, parameter_type_pointer: [*]const *llvm.Type, parameter_type_count: c_uint, is_var_arg: Bool) *llvm.Type.Function;
|
|
||||||
pub extern fn LLVMIsFunctionVarArg(function_type: *llvm.Type.Function) Bool;
|
|
||||||
pub extern fn LLVMGetReturnType(function_type: *llvm.Type.Function) *llvm.Type;
|
|
||||||
pub extern fn LLVMSetSubprogram(function: *llvm.Function, subprogram: *llvm.DI.Subprogram) void;
|
|
||||||
pub extern fn LLVMGetSubprogram(function: *llvm.Function) ?*llvm.DI.Subprogram;
|
|
||||||
pub extern fn LLVMCountParamTypes(function_type: *llvm.Type.Function) c_uint;
|
|
||||||
pub extern fn LLVMGetParamTypes(function_type: *llvm.Type.Function, types: [*]*llvm.Type) void;
|
|
||||||
|
|
||||||
// Types: struct
|
|
||||||
pub extern fn LLVMStructSetBody(struct_type: *llvm.Type.Struct, element_type_pointer: [*]const *llvm.Type, element_type_count: c_uint, is_packed: Bool) void;
|
|
||||||
pub extern fn llvm_context_create_forward_declared_struct_type(context: *llvm.Context, name: llvm.String) *llvm.Type.Struct;
|
|
||||||
pub extern fn llvm_context_create_struct_type(context: *llvm.Context, element_types_pointer: [*]const *llvm.Type, element_type_count: usize, name: llvm.String, is_packed: bool) *llvm.Type.Struct;
|
|
||||||
pub extern fn llvm_context_get_struct_type(context: *llvm.Context, element_types_pointer: [*]const *llvm.Type, element_type_count: usize, is_packed: bool) *llvm.Type.Struct;
|
|
||||||
|
|
||||||
// Types: arrays
|
|
||||||
pub extern fn LLVMArrayType2(element_type: *llvm.Type, element_count: u64) *llvm.Type.Array;
|
|
||||||
|
|
||||||
// Types: pointers
|
|
||||||
pub extern fn LLVMPointerTypeInContext(context: *llvm.Context, address_space: c_uint) *llvm.Type.Pointer;
|
|
||||||
|
|
||||||
// Types: vectors
|
|
||||||
pub extern fn LLVMVectorType(element_type: *llvm.Type, element_count: c_uint) *llvm.Type.FixedVector;
|
|
||||||
pub extern fn LLVMScalableVectorType(element_type: *llvm.Type, element_count: c_uint) *llvm.Type.ScalableVector;
|
|
||||||
|
|
||||||
pub extern fn LLVMGetTypeKind(ty: *llvm.Type) llvm.Type.Kind;
|
|
||||||
|
|
||||||
pub extern fn llvm_integer_type_get_bit_count(integer_type: *llvm.Type.Integer) c_uint;
|
|
||||||
|
|
||||||
// VALUES
|
|
||||||
pub extern fn LLVMGetPoison(type: *llvm.Type) *llvm.Value;
|
|
||||||
pub extern fn LLVMConstNeg(constant: *llvm.Constant) *llvm.Constant;
|
|
||||||
pub extern fn LLVMConstNull(type: *llvm.Type) *llvm.Constant;
|
|
||||||
pub extern fn LLVMConstInt(type: *llvm.Type.Integer, value: c_ulonglong, sign_extend: Bool) *llvm.Constant.Integer;
|
|
||||||
pub extern fn LLVMConstIntGetZExtValue(constant: *llvm.Constant) u64;
|
|
||||||
pub extern fn LLVMConstIntGetSExtValue(constant: *llvm.Constant) i64;
|
|
||||||
pub extern fn LLVMConstArray2(element_type: *llvm.Type, value_pointer: [*]const *llvm.Constant, value_length: u64) *llvm.Constant;
|
|
||||||
pub extern fn LLVMConstStructInContext(context: *llvm.Context, constant_value_pointer: [*]const *llvm.Constant, constant_value_count: c_uint, is_packed: c_uint) *llvm.Constant;
|
|
||||||
pub extern fn LLVMConstNamedStruct(struct_type: *llvm.Type.Struct, constant_value_pointer: [*]const *llvm.Constant, constant_value_count: c_uint) *llvm.Constant;
|
|
||||||
pub extern fn LLVMConstStringInContext2(context: *llvm.Context, string_pointer: [*]const u8, string_length: usize, dont_null_terminate: Bool) *llvm.Constant;
|
|
||||||
|
|
||||||
pub extern fn LLVMGetValueKind(value: *llvm.Value) llvm.Value.Kind;
|
|
||||||
pub extern fn LLVMIsConstant(value: *llvm.Value) Bool;
|
|
||||||
|
|
||||||
// Debug info API
|
|
||||||
pub extern fn LLVMCreateDIBuilder(module: *llvm.Module) *llvm.DI.Builder;
|
|
||||||
pub extern fn LLVMDIBuilderFinalize(builder: *llvm.DI.Builder) void;
|
|
||||||
pub extern fn LLVMDIBuilderCreateFile(builder: *llvm.DI.Builder, file_name: llvm.String, directory_name: llvm.String) *llvm.DI.File;
|
|
||||||
pub extern fn LLVMDIBuilderCreateCompileUnit(builder: *llvm.DI.Builder, language: llvm.Dwarf.SourceLanguage, file: *llvm.DI.File, producer_name: llvm.String, optimized: Bool, flags: llvm.String, runtime_version: c_uint, split_name: llvm.String, dwarf_emission_kind: llvm.Dwarf.EmissionKind, debug_with_offset_id: c_uint, split_debug_inlining: Bool, debug_info_for_profiling: Bool, sysroot: llvm.String, sdk: llvm.String) *llvm.DI.CompileUnit;
|
|
||||||
pub extern fn LLVMDIBuilderCreateSubroutineType(builder: *llvm.DI.Builder, file: *llvm.DI.File, parameter_type_pointer: [*]const *llvm.DI.Type, parameter_type_count: c_uint, flags: llvm.DI.Flags) *llvm.DI.Type.Subroutine;
|
|
||||||
pub extern fn LLVMDIBuilderCreateFunction(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name: llvm.String, linkage_name: llvm.String, file: *llvm.DI.File, line_number: c_uint, type: *llvm.DI.Type.Subroutine, local_to_unit: Bool, is_definition: Bool, scope_line: c_uint, flags: llvm.DI.Flags, is_optimized: Bool) *llvm.DI.Subprogram;
|
|
||||||
pub extern fn LLVMDIBuilderFinalizeSubprogram(builder: *llvm.DI.Builder, subprogram: *llvm.DI.Subprogram) void;
|
|
||||||
pub extern fn LLVMDIBuilderCreateExpression(builder: *llvm.DI.Builder, address: ?[*]const u64, length: u64) *llvm.DI.Expression;
|
|
||||||
pub extern fn LLVMDIBuilderCreateDebugLocation(context: *llvm.Context, line: c_uint, column: c_uint, scope: *llvm.DI.Scope, inlined_at: ?*llvm.DI.Metadata) *llvm.DI.Location;
|
|
||||||
pub extern fn LLVMDIBuilderCreateBasicType(builder: *llvm.DI.Builder, name_pointer: [*]const u8, name_length: usize, bit_count: u64, dwarf_type: llvm.Dwarf.Type, flags: llvm.DI.Flags) *llvm.DI.Type;
|
|
||||||
pub extern fn LLVMDIBuilderCreateAutoVariable(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line: c_uint, type: *llvm.DI.Type, always_preserve: Bool, flags: llvm.DI.Flags, align_in_bits: u32) *llvm.DI.LocalVariable;
|
|
||||||
pub extern fn LLVMDIBuilderInsertDeclareRecordAtEnd(builder: *llvm.DI.Builder, storage: *llvm.Value, local_variable: *llvm.DI.LocalVariable, expression: *llvm.DI.Expression, debug_location: *llvm.DI.Location, basic_block: *llvm.BasicBlock) *llvm.DI.Record;
|
|
||||||
pub extern fn LLVMDIBuilderCreateParameterVariable(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, argument_number: c_uint, file: *llvm.DI.File, line: c_uint, type: *llvm.DI.Type, always_preserve: Bool, flags: llvm.DI.Flags) *llvm.DI.LocalVariable;
|
|
||||||
pub extern fn LLVMDIBuilderCreateGlobalVariableExpression(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, linkage_name_pointer: [*]const u8, linkage_name_length: usize, file: *llvm.DI.File, line: c_uint, global_type: *llvm.DI.Type, local_to_unit: Bool, expression: *llvm.DI.Expression, declaration: ?*llvm.DI.Metadata, align_in_bits: u32) *llvm.DI.GlobalVariableExpression;
|
|
||||||
pub extern fn llvm_global_variable_add_debug_info(global_variable: *llvm.GlobalVariable, debug_global_variable: *llvm.DI.GlobalVariableExpression) void;
|
|
||||||
pub extern fn LLVMDIBuilderCreateLexicalBlock(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, file: *llvm.DI.File, line: c_uint, column: c_uint) *llvm.DI.LexicalBlock;
|
|
||||||
pub extern fn LLVMDIBuilderCreateReplaceableCompositeType(builder: *llvm.DI.Builder, tag: c_uint, name_pointer: [*]const u8, name_length: usize, scope: *llvm.DI.Scope, file: *llvm.DI.File, line: c_uint, runtime_language: c_uint, bit_size: u64, align_in_bits: u32, flags: llvm.DI.Flags, unique_identifier_pointer: ?[*]const u8, unique_identifier_length: usize) *llvm.DI.Type.Composite;
|
|
||||||
pub extern fn LLVMDIBuilderCreateArrayType(builder: *llvm.DI.Builder, element_count: u64, align_in_bits: u32, element_type: *llvm.DI.Type, subscript_pointer: ?[*]const *llvm.DI.Metadata, subscript_count: c_uint) *llvm.DI.Type.Composite;
|
|
||||||
pub extern fn LLVMDIBuilderCreateStructType(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, flags: llvm.DI.Flags, derived_from: ?*llvm.DI.Type, member_pointer: [*]const *llvm.DI.Type.Derived, member_length: c_uint, runtime_language: c_uint, vtable_holder: ?*llvm.DI.Metadata, unique_id_pointer: ?[*]const u8, unique_id_length: usize) *llvm.DI.Type.Composite;
|
|
||||||
pub extern fn LLVMDIBuilderCreateMemberType(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, bit_offset: u64, flags: llvm.DI.Flags, member_type: *llvm.DI.Type) *llvm.DI.Type.Derived;
|
|
||||||
pub extern fn LLVMDIBuilderCreateBitFieldMemberType(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line: c_uint, bit_size: u64, bit_offset: u64, bit_storage_offset: u64, flags: llvm.DI.Flags, member_type: *llvm.DI.Type) *llvm.DI.Type.Derived;
|
|
||||||
pub extern fn LLVMDIBuilderCreatePointerType(builder: *llvm.DI.Builder, element_type: *llvm.DI.Type, bit_size: u64, align_in_bits: u32, address_space: c_uint, name_pointer: [*]const u8, name_length: usize) *llvm.DI.Type.Derived;
|
|
||||||
pub extern fn LLVMDIBuilderCreateEnumerator(builder: *llvm.DI.Builder, name_pointer: [*]const u8, name_length: usize, value: i64, is_unsigned: Bool) *llvm.DI.Enumerator;
|
|
||||||
pub extern fn LLVMDIBuilderCreateEnumerationType(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, enumerator_pointer: [*]const *llvm.DI.Enumerator, enumerator_count: c_uint, backing_type: *llvm.DI.Type) *llvm.DI.Type.Composite;
|
|
||||||
|
|
||||||
pub extern fn LLVMMetadataReplaceAllUsesWith(forward: *llvm.DI.Type.Composite, complete: *llvm.DI.Type.Composite) void;
|
|
||||||
|
|
||||||
// Target
|
|
||||||
pub extern fn llvm_default_target_triple() llvm.String;
|
|
||||||
pub extern fn llvm_host_cpu_name() llvm.String;
|
|
||||||
pub extern fn llvm_host_cpu_features() llvm.String;
|
|
||||||
|
|
||||||
pub extern fn llvm_create_target_machine(create: *const llvm.Target.Machine.Create, error_message: *llvm.String) ?*llvm.Target.Machine;
|
|
||||||
pub extern fn llvm_module_set_target(module: *llvm.Module, target_machine: *llvm.Target.Machine) void;
|
|
||||||
|
|
||||||
pub extern fn llvm_module_run_optimization_pipeline(module: *llvm.Module, target_machine: *llvm.Target.Machine, options: llvm.OptimizationPipelineOptions) void;
|
|
||||||
pub extern fn llvm_module_run_code_generation_pipeline(module: *llvm.Module, target_machine: *llvm.Target.Machine, options: llvm.CodeGenerationPipelineOptions) llvm.CodeGenerationPipelineResult;
|
|
||||||
|
|
||||||
pub fn get_initializer(comptime llvm_arch: llvm.Architecture) type {
|
|
||||||
const arch_name = @tagName(llvm_arch);
|
|
||||||
return struct {
|
|
||||||
pub const initialize_target_info = @extern(*const fn () callconv(.C) void, .{
|
|
||||||
.name = "LLVMInitialize" ++ arch_name ++ "TargetInfo",
|
|
||||||
});
|
|
||||||
pub const initialize_target = @extern(*const fn () callconv(.C) void, .{
|
|
||||||
.name = "LLVMInitialize" ++ arch_name ++ "Target",
|
|
||||||
});
|
|
||||||
pub const initialize_target_mc = @extern(*const fn () callconv(.C) void, .{
|
|
||||||
.name = "LLVMInitialize" ++ arch_name ++ "TargetMC",
|
|
||||||
});
|
|
||||||
pub const initialize_asm_printer = @extern(*const fn () callconv(.C) void, .{
|
|
||||||
.name = "LLVMInitialize" ++ arch_name ++ "AsmPrinter",
|
|
||||||
});
|
|
||||||
pub const initialize_asm_parser = @extern(*const fn () callconv(.C) void, .{
|
|
||||||
.name = "LLVMInitialize" ++ arch_name ++ "AsmParser",
|
|
||||||
});
|
|
||||||
pub const initialize_disassembler = @extern(*const fn () callconv(.C) void, .{
|
|
||||||
.name = "LLVMInitialize" ++ arch_name ++ "Disassembler",
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn initialize(options: llvm.TargetInitializerOptions) void {
|
|
||||||
initialize_target_info();
|
|
||||||
initialize_target();
|
|
||||||
initialize_target_mc();
|
|
||||||
|
|
||||||
if (options.asm_printer) {
|
|
||||||
initialize_asm_printer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.asm_parser) {
|
|
||||||
initialize_asm_parser();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.disassembler) {
|
|
||||||
initialize_disassembler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// LLD
|
|
||||||
|
|
||||||
pub extern fn lld_elf_link(argument_pointer: [*:null]const ?[*:0]const u8, argument_length: u64, exit_early: bool, disable_output: bool) lld.Result;
|
|
4
src/main.nat
Normal file
4
src/main.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
317
src/main.zig
317
src/main.zig
@ -1,317 +0,0 @@
|
|||||||
const lib = @import("lib.zig");
|
|
||||||
const configuration = @import("configuration");
|
|
||||||
const os = lib.os;
|
|
||||||
const llvm = @import("LLVM.zig");
|
|
||||||
const Arena = lib.Arena;
|
|
||||||
|
|
||||||
const compiler = @import("bootstrap.zig");
|
|
||||||
const BuildMode = compiler.BuildMode;
|
|
||||||
|
|
||||||
test {
|
|
||||||
_ = lib;
|
|
||||||
_ = llvm;
|
|
||||||
_ = compiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fail() noreturn {
|
|
||||||
lib.libc.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Command = enum {
|
|
||||||
@"test",
|
|
||||||
compile,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Compile = struct {
|
|
||||||
relative_file_path: [:0]const u8,
|
|
||||||
build_mode: BuildMode,
|
|
||||||
has_debug_info: bool,
|
|
||||||
silent: bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn compile_file(arena: *Arena, compile: Compile) compiler.Options {
|
|
||||||
const relative_file_path = compile.relative_file_path;
|
|
||||||
if (relative_file_path.len < 5) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
const extension_start = lib.string.last_character(relative_file_path, '.') orelse fail();
|
|
||||||
if (!lib.string.equal(relative_file_path[extension_start..], ".bbb")) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
const separator_index = lib.string.last_character(relative_file_path, '/') orelse 0;
|
|
||||||
const base_start = separator_index + @intFromBool(separator_index != 0 or relative_file_path[separator_index] == '/');
|
|
||||||
const base_name = relative_file_path[base_start..extension_start];
|
|
||||||
|
|
||||||
const is_compiler = lib.string.equal(relative_file_path, "src/compiler.bbb");
|
|
||||||
const output_path_dir = arena.join_string(&.{
|
|
||||||
base_cache_dir,
|
|
||||||
if (is_compiler) "/compiler/" else "/",
|
|
||||||
@tagName(compile.build_mode),
|
|
||||||
"_",
|
|
||||||
if (compile.has_debug_info) "di" else "nodi",
|
|
||||||
});
|
|
||||||
|
|
||||||
os.make_directory(base_cache_dir);
|
|
||||||
if (is_compiler) {
|
|
||||||
os.make_directory(base_cache_dir ++ "/compiler");
|
|
||||||
}
|
|
||||||
|
|
||||||
os.make_directory(output_path_dir);
|
|
||||||
|
|
||||||
const output_path_base = arena.join_string(&.{
|
|
||||||
output_path_dir,
|
|
||||||
"/",
|
|
||||||
base_name,
|
|
||||||
});
|
|
||||||
|
|
||||||
const output_object_path = arena.join_string(&.{ output_path_base, ".o" });
|
|
||||||
const output_executable_path = output_path_base;
|
|
||||||
|
|
||||||
const file_content = lib.file.read(arena, relative_file_path);
|
|
||||||
const file_path = os.absolute_path(arena, relative_file_path);
|
|
||||||
const c_abi_object_path = arena.duplicate_string(configuration.c_abi_object_path);
|
|
||||||
|
|
||||||
const convert_options = compiler.Options{
|
|
||||||
.executable = output_executable_path,
|
|
||||||
.objects = if (lib.string.equal(base_name, "c_abi")) &.{ output_object_path, c_abi_object_path } else &.{output_object_path},
|
|
||||||
.name = base_name,
|
|
||||||
.build_mode = compile.build_mode,
|
|
||||||
.content = file_content,
|
|
||||||
.path = file_path,
|
|
||||||
.has_debug_info = compile.has_debug_info,
|
|
||||||
.target = compiler.Target.get_native(),
|
|
||||||
.silent = compile.silent,
|
|
||||||
};
|
|
||||||
|
|
||||||
compiler.compile(arena, convert_options);
|
|
||||||
|
|
||||||
return convert_options;
|
|
||||||
}
|
|
||||||
|
|
||||||
const base_cache_dir = "bb-cache";
|
|
||||||
|
|
||||||
pub const panic = lib.panic_struct;
|
|
||||||
pub const std_options = lib.std_options;
|
|
||||||
pub const main = lib.main;
|
|
||||||
|
|
||||||
pub fn entry_point(arguments: []const [*:0]const u8, environment: [*:null]const ?[*:0]const u8) void {
|
|
||||||
lib.GlobalState.initialize();
|
|
||||||
const arena = lib.global.arena;
|
|
||||||
|
|
||||||
if (arguments.len < 2) {
|
|
||||||
lib.print_string("error: Not enough arguments\n");
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
const command = lib.string.to_enum(Command, lib.cstring.to_slice(arguments[1])) orelse fail();
|
|
||||||
|
|
||||||
switch (command) {
|
|
||||||
.compile => {
|
|
||||||
if (arguments.len < 3) {
|
|
||||||
lib.libc.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var build_mode = compiler.BuildMode.debug_none;
|
|
||||||
var has_debug_info = true;
|
|
||||||
|
|
||||||
if (arguments.len >= 4) {
|
|
||||||
const build_mode_string = lib.cstring.to_slice(arguments[3]);
|
|
||||||
build_mode = lib.string.to_enum(compiler.BuildMode, build_mode_string) orelse lib.libc.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.len >= 5) {
|
|
||||||
const has_debug_info_string = lib.cstring.to_slice(arguments[4]);
|
|
||||||
has_debug_info = if (lib.string.equal(has_debug_info_string, "true")) true else if (lib.string.equal(has_debug_info_string, "false")) false else lib.libc.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const relative_file_path = lib.cstring.to_slice(arguments[2]);
|
|
||||||
_ = compile_file(arena, .{
|
|
||||||
.relative_file_path = relative_file_path,
|
|
||||||
.build_mode = build_mode,
|
|
||||||
.has_debug_info = has_debug_info,
|
|
||||||
.silent = false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
.@"test" => {
|
|
||||||
if (arguments.len != 2) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
const stop_at_failure = true;
|
|
||||||
|
|
||||||
var build_modes: [@typeInfo(BuildMode).@"enum".fields.len]BuildMode = undefined;
|
|
||||||
inline for (@typeInfo(BuildMode).@"enum".fields, 0..) |field, field_index| {
|
|
||||||
const build_mode = @field(BuildMode, field.name);
|
|
||||||
build_modes[field_index] = build_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (names) |name| {
|
|
||||||
for (build_modes) |build_mode| {
|
|
||||||
for ([2]bool{ true, false }) |has_debug_info| {
|
|
||||||
const position = arena.position;
|
|
||||||
defer arena.restore(position);
|
|
||||||
|
|
||||||
const relative_file_path = arena.join_string(&.{ "tests/", name, ".bbb" });
|
|
||||||
const compile_result = compile_file(arena, .{
|
|
||||||
.relative_file_path = relative_file_path,
|
|
||||||
.build_mode = build_mode,
|
|
||||||
.has_debug_info = has_debug_info,
|
|
||||||
.silent = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = lib.os.run_child_process(arena, &.{compile_result.executable}, environment, .{
|
|
||||||
.stdout = .inherit,
|
|
||||||
.stderr = .inherit,
|
|
||||||
.null_file_descriptor = null,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.is_successful()) {
|
|
||||||
lib.print_string("[BOOTSTRAP] Failed to run test ");
|
|
||||||
lib.print_string(name);
|
|
||||||
lib.print_string(" with build mode ");
|
|
||||||
lib.print_string(@tagName(build_mode));
|
|
||||||
lib.print_string("\n");
|
|
||||||
|
|
||||||
if (stop_at_failure) {
|
|
||||||
lib.libc.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const relative_file_path = arena.join_string(&.{"src/compiler.bbb"});
|
|
||||||
for (build_modes) |build_mode| {
|
|
||||||
for ([2]bool{ true, false }) |has_debug_info| {
|
|
||||||
const position = arena.position;
|
|
||||||
defer arena.restore(position);
|
|
||||||
|
|
||||||
const compile_result = compile_file(arena, .{
|
|
||||||
.relative_file_path = relative_file_path,
|
|
||||||
.build_mode = build_mode,
|
|
||||||
.has_debug_info = has_debug_info,
|
|
||||||
.silent = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
for (names[0..1]) |name| {
|
|
||||||
for (build_modes) |self_hosted_build_mode| {
|
|
||||||
for ([2]bool{ true, false }) |self_hosted_has_debug_info| {
|
|
||||||
const self_hosted_relative_file_path = arena.join_string(&.{ "tests/", name, ".bbb" });
|
|
||||||
// TODO: investigar corrupcion de memoria en compile_result.executable porque compile_file borra la memoria
|
|
||||||
const result = lib.os.run_child_process(arena, &.{ compile_result.executable, "compile", self_hosted_relative_file_path, @tagName(self_hosted_build_mode), if (self_hosted_has_debug_info) "true" else "false" }, environment, .{
|
|
||||||
.stdout = .inherit,
|
|
||||||
.stderr = .inherit,
|
|
||||||
.null_file_descriptor = null,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.is_successful()) {
|
|
||||||
lib.print_string("[SELF-HOSTED] Failed to compile ");
|
|
||||||
lib.print_string(name);
|
|
||||||
lib.print_string(" with build mode ");
|
|
||||||
lib.print_string(@tagName(build_mode));
|
|
||||||
lib.print_string(" and debug info ");
|
|
||||||
lib.print_string(if (has_debug_info) "on" else "off");
|
|
||||||
lib.print_string(", with self-hosted build mode ");
|
|
||||||
lib.print_string(@tagName(self_hosted_build_mode));
|
|
||||||
lib.print_string(" and self-hosted debug info ");
|
|
||||||
lib.print_string(if (self_hosted_has_debug_info) "on" else "off");
|
|
||||||
lib.print_string("\n");
|
|
||||||
|
|
||||||
if (stop_at_failure) {
|
|
||||||
lib.libc.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const names = &[_][]const u8{
|
|
||||||
"minimal",
|
|
||||||
"comments",
|
|
||||||
"constant_add",
|
|
||||||
"constant_and",
|
|
||||||
"constant_div",
|
|
||||||
"constant_mul",
|
|
||||||
"constant_rem",
|
|
||||||
"constant_or",
|
|
||||||
"constant_sub",
|
|
||||||
"constant_xor",
|
|
||||||
"constant_shift_left",
|
|
||||||
"constant_shift_right",
|
|
||||||
"minimal_stack",
|
|
||||||
"minimal_stack_arithmetic",
|
|
||||||
"minimal_stack_arithmetic2",
|
|
||||||
"minimal_stack_arithmetic3",
|
|
||||||
"extend",
|
|
||||||
"stack_negation",
|
|
||||||
"stack_add",
|
|
||||||
"stack_sub",
|
|
||||||
"integer_max",
|
|
||||||
"integer_hex",
|
|
||||||
"basic_pointer",
|
|
||||||
"basic_call",
|
|
||||||
"pointer",
|
|
||||||
"pointer_cast",
|
|
||||||
"u1_return",
|
|
||||||
"local_type_inference",
|
|
||||||
"global",
|
|
||||||
"function_pointer",
|
|
||||||
"extern",
|
|
||||||
"byte_size",
|
|
||||||
"basic_branch",
|
|
||||||
"basic_array",
|
|
||||||
"basic_enum",
|
|
||||||
"argv",
|
|
||||||
"assignment_operators",
|
|
||||||
"basic_enum",
|
|
||||||
"basic_slice",
|
|
||||||
"basic_string",
|
|
||||||
"basic_varargs",
|
|
||||||
"basic_while",
|
|
||||||
"not_pointer",
|
|
||||||
"bits",
|
|
||||||
"bits_no_backing_type",
|
|
||||||
"bits_return_u1",
|
|
||||||
"bits_zero",
|
|
||||||
"comparison",
|
|
||||||
"global_struct",
|
|
||||||
"if_no_else",
|
|
||||||
"if_no_else_void",
|
|
||||||
"indirect",
|
|
||||||
"indirect_struct",
|
|
||||||
"indirect_varargs",
|
|
||||||
"ret_c_bool",
|
|
||||||
"return_type_builtin",
|
|
||||||
"return_u64_u64",
|
|
||||||
"select",
|
|
||||||
"slice",
|
|
||||||
"small_struct_ints",
|
|
||||||
"struct_assignment",
|
|
||||||
"struct",
|
|
||||||
"struct_u64_u64",
|
|
||||||
"struct_varargs",
|
|
||||||
"struct_zero",
|
|
||||||
"unreachable",
|
|
||||||
"varargs",
|
|
||||||
"c_abi0",
|
|
||||||
"c_abi1",
|
|
||||||
"c_med_struct_ints",
|
|
||||||
"c_ret_struct_array",
|
|
||||||
"c_split_struct_ints",
|
|
||||||
"c_string_to_slice",
|
|
||||||
"c_struct_with_array",
|
|
||||||
"c_function_pointer",
|
|
||||||
"c_abi",
|
|
||||||
"string_to_enum",
|
|
||||||
"abi_enum_bool",
|
|
||||||
"empty_if",
|
|
||||||
"else_if",
|
|
||||||
"else_if_complicated",
|
|
||||||
};
|
|
@ -1,20 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
export fn enable_signal_handlers() void {
|
|
||||||
std.debug.attachSegfaultHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn dump_stack_trace(return_address: usize) void {
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
|
||||||
if (@import("builtin").strip_debug_info) {
|
|
||||||
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
|
|
||||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
std.debug.writeCurrentStackTrace(stderr, debug_info, std.io.tty.detectConfig(std.io.getStdErr()), return_address) catch |err| {
|
|
||||||
stderr.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch return;
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
4
tests/add_sub.nat
Normal file
4
tests/add_sub.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 1 - 1 + 1 - 1;
|
||||||
|
}
|
4
tests/and.nat
Normal file
4
tests/and.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 1 & 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,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,6 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
>pointer = &a;
|
|
||||||
return pointer.&;
|
|
||||||
}
|
|
@ -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,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,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;
|
|
||||||
}
|
|
166
tests/break_continue.nat
Normal file
166
tests/break_continue.nat
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
fn fn0(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a = arg;
|
||||||
|
while (a < 10)
|
||||||
|
{
|
||||||
|
a = a + 1;
|
||||||
|
if (a == 5)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == 6)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn1(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = 1;
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
i = i + 1;
|
||||||
|
if (i == 5)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 7)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = a + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn2(arg: s32) s32
|
||||||
|
{
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
i = i + 1;
|
||||||
|
if (i == 5)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 6)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn3(arg: s32) s32
|
||||||
|
{
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
i = i + 1;
|
||||||
|
if (i == 6)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn4(arg: s32) s32
|
||||||
|
{
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
i = i + 1;
|
||||||
|
if (i == 5)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i == 6)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn5(arg: s32) s32
|
||||||
|
{
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
i = i + 1;
|
||||||
|
if (i == 5)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn6(arg: s32) s32
|
||||||
|
{
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
>a = i + 2;
|
||||||
|
if (a > 4)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn7(arg: s32) s32
|
||||||
|
{
|
||||||
|
>i = arg;
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn8(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
a = a + 1;
|
||||||
|
if (a < 10)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn[cc(.c)] main[export]() s32
|
||||||
|
{
|
||||||
|
return fn0(0) +
|
||||||
|
fn1(1) +
|
||||||
|
fn2(2) +
|
||||||
|
fn3(3) +
|
||||||
|
fn4(4) +
|
||||||
|
fn5(5) +
|
||||||
|
fn6(6) +
|
||||||
|
fn7(7) +
|
||||||
|
fn8(8);
|
||||||
|
}
|
@ -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);
|
|
||||||
}
|
|
5487
tests/c_abi.c
5487
tests/c_abi.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
|
||||||
}
|
|
4
tests/comparison.nat
Normal file
4
tests/comparison.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main (argc: s32) s32
|
||||||
|
{
|
||||||
|
return argc != 1;
|
||||||
|
}
|
@ -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,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;
|
|
||||||
}
|
|
4
tests/constant_prop.nat
Normal file
4
tests/constant_prop.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn[cc(.c)] main [export] () s32
|
||||||
|
{
|
||||||
|
return 2 + 4 - 1 - 5;
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
4
tests/div.nat
Normal file
4
tests/div.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 0 / 1;
|
||||||
|
}
|
@ -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,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);
|
|
||||||
}
|
|
4
tests/first.nat
Normal file
4
tests/first.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main () s32
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
10
tests/function_call_args.nat
Normal file
10
tests/function_call_args.nat
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn foo(arg: s32) s32
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn[cc(.c)] main [export] () s32
|
||||||
|
{
|
||||||
|
>arg: s32 = 6;
|
||||||
|
return foo(arg) - arg;
|
||||||
|
}
|
@ -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,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;
|
|
||||||
}
|
|
131
tests/if.nat
Normal file
131
tests/if.nat
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
fn if0(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = 1;
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
a = arg + 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = arg - 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if1(arg: s32) s32
|
||||||
|
{
|
||||||
|
>c: s32 = 3;
|
||||||
|
>b: s32 = 2;
|
||||||
|
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
b = 3;
|
||||||
|
c = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if2(arg: s32) s32
|
||||||
|
{
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if3(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = arg + 1;
|
||||||
|
>b: s32 = 0;
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b = a + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if4(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = arg + 1;
|
||||||
|
>b: s32 = arg + 2;
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
b = b + a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = b + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if5(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = 1;
|
||||||
|
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
if (arg == 2)
|
||||||
|
{
|
||||||
|
a = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (arg == 3)
|
||||||
|
{
|
||||||
|
a = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if6(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = 0;
|
||||||
|
>b: s32 = 0;
|
||||||
|
if (arg)
|
||||||
|
{
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
if (arg == 0)
|
||||||
|
{
|
||||||
|
b = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg + a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if7(arg: s32) s32
|
||||||
|
{
|
||||||
|
>a: s32 = arg == 2;
|
||||||
|
if (arg == 1)
|
||||||
|
{
|
||||||
|
a = arg == 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn[cc(.c)] main[export] () s32
|
||||||
|
{
|
||||||
|
return if0(3) + if1(1) - 4 + if2(1) - 3 + if3(1) - 4 + if4(0) - 5 + if5(4) - 5 + if6(0) - 2 + if7(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,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 @@
|
|||||||
foo = fn() s32
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
>result = foo() + a;
|
|
||||||
return result;
|
|
||||||
}
|
|
1000001
tests/million_simple_functions.nat
Normal file
1000001
tests/million_simple_functions.nat
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 1;
|
|
||||||
>b = 1 - a;
|
|
||||||
return b;
|
|
||||||
}
|
|
4
tests/mul.nat
Normal file
4
tests/mul.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 1 * 0;
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>a: s32 = 0;
|
|
||||||
>ptr = &a;
|
|
||||||
>b = !ptr;
|
|
||||||
return #extend(b);
|
|
||||||
}
|
|
4
tests/or.nat
Normal file
4
tests/or.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 0 | 0;
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
modify = fn (v: &s32) void
|
|
||||||
{
|
|
||||||
v.& = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>value: s32 = 0;
|
|
||||||
modify(&value);
|
|
||||||
return #extend(value == 0);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>result: u32 = 0;
|
|
||||||
>pointer = &result;
|
|
||||||
>signed_ptr: &s32 = #pointer_cast(pointer);
|
|
||||||
return signed_ptr.&;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
ret_c_bool = fn [cc(c)] () u8
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
return #extend(ret_c_bool());
|
|
||||||
}
|
|
10
tests/return_mod_scope.nat
Normal file
10
tests/return_mod_scope.nat
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
>a: s32 = 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
[export] main = fn () s32
|
|
||||||
{
|
|
||||||
>result: #ReturnType = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
Struct_u64_u64 = struct
|
|
||||||
{
|
|
||||||
a: u64,
|
|
||||||
b: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
return_struct_u64_u64 = fn [cc(c)] () Struct_u64_u64
|
|
||||||
{
|
|
||||||
return { .a = 1, .b = 2 };
|
|
||||||
}
|
|
||||||
|
|
||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>r = return_struct_u64_u64();
|
|
||||||
return #truncate(r.a + r.b - 3);
|
|
||||||
}
|
|
5
tests/return_var.nat
Normal file
5
tests/return_var.nat
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
>a: s32 = 0;
|
||||||
|
return a;
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
[export] main = fn [cc(c)] () s32
|
|
||||||
{
|
|
||||||
>boolean: u1 = 1;
|
|
||||||
>true_value: s32 = 0;
|
|
||||||
>false_value: s32 = 1;
|
|
||||||
return #select(boolean, true_value, false_value);
|
|
||||||
}
|
|
4
tests/shift_left.nat
Normal file
4
tests/shift_left.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 0 << 1;
|
||||||
|
}
|
4
tests/shift_right.nat
Normal file
4
tests/shift_right.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() s32
|
||||||
|
{
|
||||||
|
return 1 >> 1;
|
||||||
|
}
|
4
tests/simple_arg.nat
Normal file
4
tests/simple_arg.nat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main(argument_count: s32) s32
|
||||||
|
{
|
||||||
|
return argument_count - 1;
|
||||||
|
}
|
9
tests/simple_variable_declaration.nat
Normal file
9
tests/simple_variable_declaration.nat
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn[cc(.c)] main [export] () s32
|
||||||
|
{
|
||||||
|
>a: s32 = 2;
|
||||||
|
>b: s32 = 2;
|
||||||
|
{
|
||||||
|
>c: s32 = a - b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
@ -1,34 +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;
|
|
||||||
}
|
|
||||||
>arg_ptr = argument_pointer[0];
|
|
||||||
>a1 = arg_ptr[0..c_string_length(arg_ptr)];
|
|
||||||
>a2 = a1[1..];
|
|
||||||
|
|
||||||
if (a1.pointer != a2.pointer - 1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a1.length != a2.length + 1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
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