Merge remote-tracking branch 'origin/master' into llvm6

master
Andrew Kelley 2018-01-25 11:51:41 -05:00
commit 47be64af5a
220 changed files with 5028 additions and 5350 deletions

View File

@ -5,8 +5,6 @@ clarity.
[ziglang.org](http://ziglang.org)
[Documentation](http://ziglang.org/documentation/master/)
## Feature Highlights
* Small, simple language. Focus on debugging your application rather than
@ -200,11 +198,3 @@ This is the actual compiler binary that we will install to the system.
```
./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
```
### Related Projects
* [zig-mode](https://github.com/AndreaOrru/zig-mode) - Emacs integration
* [zig.vim](https://github.com/zig-lang/zig.vim) - Vim configuration files
* [vscode-zig](https://github.com/zig-lang/vscode-zig) - Visual Studio Code extension
* [zig-compiler-completions](https://github.com/tiehuis/zig-compiler-completions) - bash and zsh completions for the zig compiler
* [NppExtension](https://github.com/ice1000/NppExtension) - Notepad++ syntax highlighting

View File

@ -10,7 +10,7 @@ const ArrayList = std.ArrayList;
const Buffer = std.Buffer;
const io = std.io;
pub fn build(b: &Builder) -> %void {
pub fn build(b: &Builder) %void {
const mode = b.standardReleaseOptions();
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
@ -116,11 +116,12 @@ pub fn build(b: &Builder) -> %void {
test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));
test_step.dependOn(tests.addDebugSafetyTests(b, test_filter));
test_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter));
test_step.dependOn(tests.addTranslateCTests(b, test_filter));
test_step.dependOn(tests.addGenHTests(b, test_filter));
}
fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) void {
for (dep.libdirs.toSliceConst()) |lib_dir| {
lib_exe_obj.addLibPath(lib_dir);
}
@ -135,7 +136,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
}
}
fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) {
fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {
const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",
b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
@ -148,7 +149,7 @@ const LibraryDep = struct {
includes: ArrayList([]const u8),
};
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) -> %LibraryDep {
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) %LibraryDep {
const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});
const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});
@ -196,7 +197,7 @@ fn findLLVM(b: &Builder, llvm_config_exe: []const u8) -> %LibraryDep {
return result;
}
pub fn installStdLib(b: &Builder, stdlib_files: []const u8) {
pub fn installStdLib(b: &Builder, stdlib_files: []const u8) void {
var it = mem.split(stdlib_files, ";");
while (it.next()) |stdlib_file| {
const src_path = os.path.join(b.allocator, "std", stdlib_file) catch unreachable;
@ -205,7 +206,7 @@ pub fn installStdLib(b: &Builder, stdlib_files: []const u8) {
}
}
pub fn installCHeaders(b: &Builder, c_header_files: []const u8) {
pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {
var it = mem.split(c_header_files, ";");
while (it.next()) |c_header_file| {
const src_path = os.path.join(b.allocator, "c_headers", c_header_file) catch unreachable;
@ -214,7 +215,7 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) {
}
}
fn nextValue(index: &usize, build_info: []const u8) -> []const u8 {
fn nextValue(index: &usize, build_info: []const u8) []const u8 {
const start = *index;
while (true) : (*index += 1) {
switch (build_info[*index]) {

View File

@ -8,6 +8,7 @@ SET "RELEASEDIR=zig-%ZIGVERSION%"
mkdir "%RELEASEDIR%"
move build-msvc-release\bin\zig.exe "%RELEASEDIR%"
move build-msvc-release\lib "%RELEASEDIR%"
move zig-cache\langref.html "%RELEASEDIR%"
SET "RELEASEZIP=zig-%ZIGVERSION%.zip"

View File

@ -1,14 +1,18 @@
const builtin = @import("builtin");
const std = @import("std");
const io = std.io;
const os = std.os;
const warn = std.debug.warn;
const mem = std.mem;
const assert = std.debug.assert;
const max_doc_file_size = 10 * 1024 * 1024;
const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
const tmp_dir_name = "docgen_tmp";
pub fn main() -> %void {
pub fn main() %void {
// TODO use a more general purpose allocator here
var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);
defer inc_allocator.deinit();
@ -43,6 +47,15 @@ pub fn main() -> %void {
var tokenizer = Tokenizer.init(in_file_name, input_file_bytes);
var toc = try genToc(allocator, &tokenizer);
try os.makePath(allocator, tmp_dir_name);
defer {
// TODO issue #709
// disabled to pass CI tests, but obviously we want to implement this
// and then remove this workaround
if (builtin.os == builtin.Os.linux) {
os.deleteTree(allocator, tmp_dir_name) catch {};
}
}
try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);
try buffered_out_stream.flush();
}
@ -68,6 +81,7 @@ const Tokenizer = struct {
index: usize,
state: State,
source_file_name: []const u8,
code_node_count: usize,
const State = enum {
Start,
@ -77,16 +91,17 @@ const Tokenizer = struct {
Eof,
};
fn init(source_file_name: []const u8, buffer: []const u8) -> Tokenizer {
fn init(source_file_name: []const u8, buffer: []const u8) Tokenizer {
return Tokenizer {
.buffer = buffer,
.index = 0,
.state = State.Start,
.source_file_name = source_file_name,
.code_node_count = 0,
};
}
fn next(self: &Tokenizer) -> Token {
fn next(self: &Tokenizer) Token {
var result = Token {
.id = Token.Id.Eof,
.start = self.index,
@ -178,7 +193,7 @@ const Tokenizer = struct {
line_end: usize,
};
fn getTokenLocation(self: &Tokenizer, token: &const Token) -> Location {
fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
var loc = Location {
.line = 0,
.column = 0,
@ -205,7 +220,7 @@ const Tokenizer = struct {
error ParseError;
fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const u8, args: ...) -> error {
fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const u8, args: ...) error {
const loc = tokenizer.getTokenLocation(token);
warn("{}:{}:{}: error: " ++ fmt ++ "\n", tokenizer.source_file_name, loc.line + 1, loc.column + 1, args);
if (loc.line_start <= loc.line_end) {
@ -228,13 +243,13 @@ fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const
return error.ParseError;
}
fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) -> %void {
fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) %void {
if (token.id != id) {
return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
}
}
fn eatToken(tokenizer: &Tokenizer, id: Token.Id) -> %Token {
fn eatToken(tokenizer: &Tokenizer, id: Token.Id) %Token {
const token = tokenizer.next();
try assertToken(tokenizer, token, id);
return token;
@ -251,24 +266,43 @@ const SeeAlsoItem = struct {
token: Token,
};
const ExpectedOutcome = enum {
Succeed,
Fail,
};
const Code = struct {
id: Id,
name: []const u8,
source_token: Token,
is_inline: bool,
mode: builtin.Mode,
link_objects: []const []const u8,
target_windows: bool,
link_libc: bool,
const Id = enum {
const Id = union(enum) {
Test,
Exe,
Error,
TestError: []const u8,
TestSafety: []const u8,
Exe: ExpectedOutcome,
Obj: ?[]const u8,
};
};
const Link = struct {
url: []const u8,
name: []const u8,
token: Token,
};
const Node = union(enum) {
Content: []const u8,
Nav,
HeaderOpen: HeaderOpen,
SeeAlso: []const SeeAlsoItem,
Code: Code,
Link: Link,
};
const Toc = struct {
@ -282,9 +316,9 @@ const Action = enum {
Close,
};
fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
var urls = std.HashMap([]const u8, Token, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator);
%defer urls.deinit();
errdefer urls.deinit();
var header_stack_size: usize = 0;
var last_action = Action.Open;
@ -365,7 +399,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
}
} else if (mem.eql(u8, tag_name, "see_also")) {
var list = std.ArrayList(SeeAlsoItem).init(allocator);
%defer list.deinit();
errdefer list.deinit();
while (true) {
const see_also_tok = tokenizer.next();
@ -385,6 +419,31 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),
}
}
} else if (mem.eql(u8, tag_name, "link")) {
_ = try eatToken(tokenizer, Token.Id.Separator);
const name_tok = try eatToken(tokenizer, Token.Id.TagContent);
const name = tokenizer.buffer[name_tok.start..name_tok.end];
const url_name = blk: {
const tok = tokenizer.next();
switch (tok.id) {
Token.Id.BracketClose => break :blk name,
Token.Id.Separator => {
const explicit_text = try eatToken(tokenizer, Token.Id.TagContent);
_ = try eatToken(tokenizer, Token.Id.BracketClose);
break :blk tokenizer.buffer[explicit_text.start..explicit_text.end];
},
else => return parseError(tokenizer, tok, "invalid link token"),
}
};
try nodes.append(Node {
.Link = Link {
.url = try urlize(allocator, url_name),
.name = name,
.token = name_tok,
},
});
} else if (mem.eql(u8, tag_name, "code_begin")) {
_ = try eatToken(tokenizer, Token.Id.Separator);
const code_kind_tok = try eatToken(tokenizer, Token.Id.TagContent);
@ -401,28 +460,71 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
}
const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
var code_kind_id: Code.Id = undefined;
var is_inline = false;
if (mem.eql(u8, code_kind_str, "exe")) {
code_kind_id = Code.Id.Exe;
code_kind_id = Code.Id { .Exe = ExpectedOutcome.Succeed };
} else if (mem.eql(u8, code_kind_str, "exe_err")) {
code_kind_id = Code.Id { .Exe = ExpectedOutcome.Fail };
} else if (mem.eql(u8, code_kind_str, "test")) {
code_kind_id = Code.Id.Test;
} else if (mem.eql(u8, code_kind_str, "error")) {
code_kind_id = Code.Id.Error;
} else if (mem.eql(u8, code_kind_str, "test_err")) {
code_kind_id = Code.Id { .TestError = name};
name = "test";
} else if (mem.eql(u8, code_kind_str, "test_safety")) {
code_kind_id = Code.Id { .TestSafety = name};
name = "test";
} else if (mem.eql(u8, code_kind_str, "obj")) {
code_kind_id = Code.Id { .Obj = null };
} else if (mem.eql(u8, code_kind_str, "obj_err")) {
code_kind_id = Code.Id { .Obj = name };
name = "test";
} else if (mem.eql(u8, code_kind_str, "syntax")) {
code_kind_id = Code.Id { .Obj = null };
is_inline = true;
} else {
return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);
}
const source_token = try eatToken(tokenizer, Token.Id.Content);
_ = try eatToken(tokenizer, Token.Id.BracketOpen);
const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);
const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];
if (!mem.eql(u8, end_tag_name, "code_end")) {
return parseError(tokenizer, end_code_tag, "expected code_end token");
}
_ = try eatToken(tokenizer, Token.Id.BracketClose);
try nodes.append(Node {.Code = Code{
var mode = builtin.Mode.Debug;
var link_objects = std.ArrayList([]const u8).init(allocator);
defer link_objects.deinit();
var target_windows = false;
var link_libc = false;
const source_token = while (true) {
const content_tok = try eatToken(tokenizer, Token.Id.Content);
_ = try eatToken(tokenizer, Token.Id.BracketOpen);
const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);
const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];
if (mem.eql(u8, end_tag_name, "code_release_fast")) {
mode = builtin.Mode.ReleaseFast;
} else if (mem.eql(u8, end_tag_name, "code_link_object")) {
_ = try eatToken(tokenizer, Token.Id.Separator);
const obj_tok = try eatToken(tokenizer, Token.Id.TagContent);
try link_objects.append(tokenizer.buffer[obj_tok.start..obj_tok.end]);
} else if (mem.eql(u8, end_tag_name, "target_windows")) {
target_windows = true;
} else if (mem.eql(u8, end_tag_name, "link_libc")) {
link_libc = true;
} else if (mem.eql(u8, end_tag_name, "code_end")) {
_ = try eatToken(tokenizer, Token.Id.BracketClose);
break content_tok;
} else {
return parseError(tokenizer, end_code_tag, "invalid token inside code_begin: {}", end_tag_name);
}
_ = try eatToken(tokenizer, Token.Id.BracketClose);
} else unreachable; // TODO issue #707
try nodes.append(Node {.Code = Code {
.id = code_kind_id,
.name = name,
.source_token = source_token,
.is_inline = is_inline,
.mode = mode,
.link_objects = link_objects.toOwnedSlice(),
.target_windows = target_windows,
.link_libc = link_libc,
}});
tokenizer.code_node_count += 1;
} else {
return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);
}
@ -438,7 +540,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
};
}
fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();
@ -458,7 +560,7 @@ fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
return buf.toOwnedSlice();
}
fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
fn escapeHtml(allocator: &mem.Allocator, input: []const u8) %[]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();
@ -476,14 +578,127 @@ fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
return buf.toOwnedSlice();
}
//#define VT_RED "\x1b[31;1m"
//#define VT_GREEN "\x1b[32;1m"
//#define VT_CYAN "\x1b[36;1m"
//#define VT_WHITE "\x1b[37;1m"
//#define VT_BOLD "\x1b[0;1m"
//#define VT_RESET "\x1b[0m"
const TermState = enum {
Start,
Escape,
LBracket,
Number,
AfterNumber,
Arg,
ArgNumber,
ExpectEnd,
};
error UnsupportedEscape;
test "term color" {
const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
const result = try termColor(std.debug.global_allocator, input_bytes);
assert(mem.eql(u8, result, "A<span class=\"t32\">green</span>B"));
}
fn termColor(allocator: &mem.Allocator, input: []const u8) %[]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();
var buf_adapter = io.BufferOutStream.init(&buf);
var out = &buf_adapter.stream;
var number_start_index: usize = undefined;
var first_number: usize = undefined;
var second_number: usize = undefined;
var i: usize = 0;
var state = TermState.Start;
var open_span_count: usize = 0;
while (i < input.len) : (i += 1) {
const c = input[i];
switch (state) {
TermState.Start => switch (c) {
'\x1b' => state = TermState.Escape,
else => try out.writeByte(c),
},
TermState.Escape => switch (c) {
'[' => state = TermState.LBracket,
else => return error.UnsupportedEscape,
},
TermState.LBracket => switch (c) {
'0'...'9' => {
number_start_index = i;
state = TermState.Number;
},
else => return error.UnsupportedEscape,
},
TermState.Number => switch (c) {
'0'...'9' => {},
else => {
first_number = std.fmt.parseInt(usize, input[number_start_index..i], 10) catch unreachable;
second_number = 0;
state = TermState.AfterNumber;
i -= 1;
},
},
TermState.AfterNumber => switch (c) {
';' => state = TermState.Arg,
else => {
state = TermState.ExpectEnd;
i -= 1;
},
},
TermState.Arg => switch (c) {
'0'...'9' => {
number_start_index = i;
state = TermState.ArgNumber;
},
else => return error.UnsupportedEscape,
},
TermState.ArgNumber => switch (c) {
'0'...'9' => {},
else => {
second_number = std.fmt.parseInt(usize, input[number_start_index..i], 10) catch unreachable;
state = TermState.ExpectEnd;
i -= 1;
},
},
TermState.ExpectEnd => switch (c) {
'm' => {
state = TermState.Start;
while (open_span_count != 0) : (open_span_count -= 1) {
try out.write("</span>");
}
if (first_number != 0 or second_number != 0) {
try out.print("<span class=\"t{}_{}\">", first_number, second_number);
open_span_count += 1;
}
},
else => return error.UnsupportedEscape,
},
}
}
return buf.toOwnedSlice();
}
error ExampleFailedToCompile;
fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) -> %void {
fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) %void {
var code_progress_index: usize = 0;
for (toc.nodes) |node| {
switch (node) {
Node.Content => |data| {
try out.write(data);
},
Node.Link => |info| {
if (!toc.urls.contains(info.url)) {
return parseError(tokenizer, info.token, "url not found: {}", info.url);
}
try out.print("<a href=\"#{}\">{}</a>", info.url, info.name);
},
Node.Nav => {
try out.write(toc.toc);
},
@ -502,65 +717,281 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io
try out.write("</ul>\n");
},
Node.Code => |code| {
code_progress_index += 1;
warn("docgen example code {}/{}...", code_progress_index, tokenizer.code_node_count);
const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
const escaped_source = try escapeHtml(allocator, trimmed_raw_source);
if (!code.is_inline) {
try out.print("<p class=\"file\">{}.zig</p>", code.name);
}
try out.print("<pre><code class=\"zig\">{}</code></pre>", escaped_source);
const tmp_dir_name = "docgen_tmp";
try os.makePath(allocator, tmp_dir_name);
const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext);
const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
try io.writeFile(tmp_source_file_name, trimmed_raw_source, null);
switch (code.id) {
Code.Id.Exe => {
{
const args = [][]const u8 {zig_exe, "build-exe", tmp_source_file_name, "--output", tmp_bin_file_name};
const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
Code.Id.Exe => |expected_outcome| {
const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
var build_args = std.ArrayList([]const u8).init(allocator);
defer build_args.deinit();
try build_args.appendSlice([][]const u8 {zig_exe,
"build-exe", tmp_source_file_name,
"--output", tmp_bin_file_name,
});
try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", code.name);
switch (code.mode) {
builtin.Mode.Debug => {},
builtin.Mode.ReleaseSafe => {
try build_args.append("--release-safe");
try out.print(" --release-safe");
},
builtin.Mode.ReleaseFast => {
try build_args.append("--release-fast");
try out.print(" --release-fast");
},
}
for (code.link_objects) |link_object| {
const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext);
const full_path_object = try os.path.join(allocator, tmp_dir_name, name_with_ext);
try build_args.append("--object");
try build_args.append(full_path_object);
try out.print(" --object {}", name_with_ext);
}
if (code.link_libc) {
try build_args.append("--library");
try build_args.append("c");
try out.print(" --library c");
}
_ = exec(allocator, build_args.toSliceConst()) catch return parseError(
tokenizer, code.source_token, "example failed to compile");
const run_args = [][]const u8 {tmp_bin_file_name};
const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
if (exit_code != 0) {
warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
for (args) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example failed to compile");
if (exit_code == 0) {
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
for (run_args) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example incorrectly compiled");
}
},
else => {},
}
break :blk result;
} else blk: {
break :blk exec(allocator, run_args) catch return parseError(
tokenizer, code.source_token, "example crashed");
};
const escaped_stderr = try escapeHtml(allocator, result.stderr);
const escaped_stdout = try escapeHtml(allocator, result.stdout);
const colored_stderr = try termColor(allocator, escaped_stderr);
const colored_stdout = try termColor(allocator, escaped_stdout);
try out.print("\n$ ./{}\n{}{}</code></pre>\n", code.name, colored_stdout, colored_stderr);
},
Code.Id.Test => {
var test_args = std.ArrayList([]const u8).init(allocator);
defer test_args.deinit();
try test_args.appendSlice([][]const u8 {zig_exe, "test", tmp_source_file_name});
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
switch (code.mode) {
builtin.Mode.Debug => {},
builtin.Mode.ReleaseSafe => {
try test_args.append("--release-safe");
try out.print(" --release-safe");
},
builtin.Mode.ReleaseFast => {
try test_args.append("--release-fast");
try out.print(" --release-fast");
},
}
if (code.target_windows) {
try test_args.appendSlice([][]const u8{
"--target-os", "windows",
"--target-arch", "x86_64",
"--target-environ", "msvc",
});
}
const result = exec(allocator, test_args.toSliceConst()) catch return parseError(
tokenizer, code.source_token, "test failed");
const escaped_stderr = try escapeHtml(allocator, result.stderr);
const escaped_stdout = try escapeHtml(allocator, result.stdout);
try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
},
Code.Id.TestError => |error_match| {
var test_args = std.ArrayList([]const u8).init(allocator);
defer test_args.deinit();
try test_args.appendSlice([][]const u8 {zig_exe, "test", "--color", "on", tmp_source_file_name});
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
switch (code.mode) {
builtin.Mode.Debug => {},
builtin.Mode.ReleaseSafe => {
try test_args.append("--release-safe");
try out.print(" --release-safe");
},
builtin.Mode.ReleaseFast => {
try test_args.append("--release-fast");
try out.print(" --release-fast");
},
}
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
if (exit_code == 0) {
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example incorrectly compiled");
}
},
else => {
warn("{}\nThe following command crashed:\n", result.stderr);
for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example compile crashed");
},
}
if (mem.indexOf(u8, result.stderr, error_match) == null) {
warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
return parseError(tokenizer, code.source_token, "example did not have expected compile error");
}
const escaped_stderr = try escapeHtml(allocator, result.stderr);
const colored_stderr = try termColor(allocator, escaped_stderr);
try out.print("\n{}</code></pre>\n", colored_stderr);
},
Code.Id.TestSafety => |error_match| {
var test_args = std.ArrayList([]const u8).init(allocator);
defer test_args.deinit();
try test_args.appendSlice([][]const u8 {zig_exe, "test", tmp_source_file_name});
switch (code.mode) {
builtin.Mode.Debug => {},
builtin.Mode.ReleaseSafe => try test_args.append("--release-safe"),
builtin.Mode.ReleaseFast => try test_args.append("--release-fast"),
}
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
if (exit_code == 0) {
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example test incorrectly succeeded");
}
},
else => {
warn("{}\nThe following command crashed:\n", result.stderr);
for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example compile crashed");
},
}
if (mem.indexOf(u8, result.stderr, error_match) == null) {
warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
return parseError(tokenizer, code.source_token, "example did not have expected runtime safety error message");
}
const escaped_stderr = try escapeHtml(allocator, result.stderr);
const colored_stderr = try termColor(allocator, escaped_stderr);
try out.print("<pre><code class=\"shell\">$ zig test {}.zig\n{}</code></pre>\n", code.name, colored_stderr);
},
Code.Id.Obj => |maybe_error_match| {
const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, obj_ext);
const tmp_obj_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_obj_ext);
var build_args = std.ArrayList([]const u8).init(allocator);
defer build_args.deinit();
try build_args.appendSlice([][]const u8 {zig_exe, "build-obj", tmp_source_file_name,
"--color", "on",
"--output", tmp_obj_file_name});
if (!code.is_inline) {
try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", code.name);
}
switch (code.mode) {
builtin.Mode.Debug => {},
builtin.Mode.ReleaseSafe => {
try build_args.append("--release-safe");
if (!code.is_inline) {
try out.print(" --release-safe");
}
},
builtin.Mode.ReleaseFast => {
try build_args.append("--release-fast");
if (!code.is_inline) {
try out.print(" --release-fast");
}
},
}
if (maybe_error_match) |error_match| {
const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
if (exit_code == 0) {
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
for (build_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example build incorrectly succeeded");
}
},
else => {
warn("{}\nThe following command crashed:\n", result.stderr);
for (args) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example failed to compile");
for (build_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example compile crashed");
},
}
if (mem.indexOf(u8, result.stderr, error_match) == null) {
warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
return parseError(tokenizer, code.source_token, "example did not have expected compile error message");
}
const escaped_stderr = try escapeHtml(allocator, result.stderr);
const colored_stderr = try termColor(allocator, escaped_stderr);
try out.print("\n{}\n", colored_stderr);
if (!code.is_inline) {
try out.print("</code></pre>\n");
}
} else {
_ = exec(allocator, build_args.toSliceConst()) catch return parseError(
tokenizer, code.source_token, "example failed to compile");
}
const args = [][]const u8 {tmp_bin_file_name};
const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
if (exit_code != 0) {
warn("The following command exited with code {}:\n", exit_code);
for (args) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example exited with code {}", exit_code);
}
},
else => {
warn("The following command crashed:\n");
for (args) |arg| warn("{} ", arg) else warn("\n");
return parseError(tokenizer, code.source_token, "example crashed");
},
if (!code.is_inline) {
try out.print("</code></pre>\n");
}
try out.print("<pre><code class=\"sh\">$ zig build-exe {}.zig\n$ ./{}\n{}{}</code></pre>\n", code.name, code.name, result.stderr, result.stdout);
},
Code.Id.Test => {
@panic("TODO");
},
Code.Id.Error => {
@panic("TODO");
},
}
warn("OK\n");
},
}
}
}
error ChildCrashed;
error ChildExitError;
fn exec(allocator: &mem.Allocator, args: []const []const u8) %os.ChildProcess.ExecResult {
const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
if (exit_code != 0) {
warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
for (args) |arg| warn("{} ", arg) else warn("\n");
return error.ChildExitError;
}
},
else => {
warn("{}\nThe following command crashed:\n", result.stderr);
for (args) |arg| warn("{} ", arg) else warn("\n");
return error.ChildCrashed;
},
}
return result;
}

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@ const os = std.os;
const warn = std.debug.warn;
const allocator = std.debug.global_allocator;
pub fn main() -> %void {
pub fn main() %void {
var args_it = os.args();
const exe = try unwrapArg(??args_it.next(allocator));
var catted_anything = false;
@ -36,12 +36,12 @@ pub fn main() -> %void {
}
}
fn usage(exe: []const u8) -> %void {
fn usage(exe: []const u8) %void {
warn("Usage: {} [FILE]...\n", exe);
return error.Invalid;
}
fn cat_file(stdout: &io.File, file: &io.File) -> %void {
fn cat_file(stdout: &io.File, file: &io.File) %void {
var buf: [1024 * 4]u8 = undefined;
while (true) {
@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {
}
}
fn unwrapArg(arg: %[]u8) -> %[]u8 {
fn unwrapArg(arg: %[]u8) %[]u8 {
return arg catch |err| {
warn("Unable to parse command line: {}\n", err);
return err;

View File

@ -5,7 +5,7 @@ const fmt = std.fmt;
const Rand = std.rand.Rand;
const os = std.os;
pub fn main() -> %void {
pub fn main() %void {
var stdout_file = try io.getStdOut();
var stdout_file_stream = io.FileOutStream.init(&stdout_file);
const stdout = &stdout_file_stream.stream;

View File

@ -1,6 +1,6 @@
const std = @import("std");
pub fn main() -> %void {
pub fn main() %void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit

View File

@ -7,7 +7,7 @@ const c = @cImport({
const msg = c"Hello, world!\n";
export fn main(argc: c_int, argv: &&u8) -> c_int {
export fn main(argc: c_int, argv: &&u8) c_int {
if (c.printf(msg) != c_int(c.strlen(msg)))
return -1;

View File

@ -1,6 +1,6 @@
use @import("std").os.windows;
export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) -> INT {
export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) INT {
_ = MessageBoxA(null, c"hello", c"title", 0);
return 0;
}

View File

@ -1,6 +1,6 @@
const base64 = @import("std").base64;
export fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) -> usize {
export fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) usize {
const src = source_ptr[0..source_len];
const dest = dest_ptr[0..dest_len];
const base64_decoder = base64.standard_decoder_unsafe;

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) -> %void {
pub fn build(b: &Builder) %void {
const obj = b.addObject("base64", "base64.zig");
const exe = b.addCExecutable("test");

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) -> %void {
pub fn build(b: &Builder) %void {
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
const exe = b.addCExecutable("test");

View File

@ -1,3 +1,3 @@
export fn add(a: i32, b: i32) -> i32 {
export fn add(a: i32, b: i32) i32 {
return a + b;
}

View File

@ -20,7 +20,7 @@ pub const Node = struct {
FloatLiteral,
};
pub fn iterate(base: &Node, index: usize) -> ?&Node {
pub fn iterate(base: &Node, index: usize) ?&Node {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
@ -35,7 +35,7 @@ pub const Node = struct {
};
}
pub fn destroy(base: &Node, allocator: &mem.Allocator) {
pub fn destroy(base: &Node, allocator: &mem.Allocator) void {
return switch (base.id) {
Id.Root => allocator.destroy(@fieldParentPtr(NodeRoot, "base", base)),
Id.VarDecl => allocator.destroy(@fieldParentPtr(NodeVarDecl, "base", base)),
@ -55,7 +55,7 @@ pub const NodeRoot = struct {
base: Node,
decls: ArrayList(&Node),
pub fn iterate(self: &NodeRoot, index: usize) -> ?&Node {
pub fn iterate(self: &NodeRoot, index: usize) ?&Node {
if (index < self.decls.len) {
return self.decls.items[self.decls.len - index - 1];
}
@ -76,7 +76,7 @@ pub const NodeVarDecl = struct {
align_node: ?&Node,
init_node: ?&Node,
pub fn iterate(self: &NodeVarDecl, index: usize) -> ?&Node {
pub fn iterate(self: &NodeVarDecl, index: usize) ?&Node {
var i = index;
if (self.type_node) |type_node| {
@ -102,7 +102,7 @@ pub const NodeIdentifier = struct {
base: Node,
name_token: Token,
pub fn iterate(self: &NodeIdentifier, index: usize) -> ?&Node {
pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {
return null;
}
};
@ -113,7 +113,7 @@ pub const NodeFnProto = struct {
fn_token: Token,
name_token: ?Token,
params: ArrayList(&Node),
return_type: ?&Node,
return_type: &Node,
var_args_token: ?Token,
extern_token: ?Token,
inline_token: ?Token,
@ -122,7 +122,7 @@ pub const NodeFnProto = struct {
lib_name: ?&Node, // populated if this is an extern declaration
align_expr: ?&Node, // populated if align(A) is present
pub fn iterate(self: &NodeFnProto, index: usize) -> ?&Node {
pub fn iterate(self: &NodeFnProto, index: usize) ?&Node {
var i = index;
if (self.body_node) |body_node| {
@ -130,10 +130,8 @@ pub const NodeFnProto = struct {
i -= 1;
}
if (self.return_type) |return_type| {
if (i < 1) return return_type;
i -= 1;
}
if (i < 1) return self.return_type;
i -= 1;
if (self.align_expr) |align_expr| {
if (i < 1) return align_expr;
@ -160,7 +158,7 @@ pub const NodeParamDecl = struct {
type_node: &Node,
var_args_token: ?Token,
pub fn iterate(self: &NodeParamDecl, index: usize) -> ?&Node {
pub fn iterate(self: &NodeParamDecl, index: usize) ?&Node {
var i = index;
if (i < 1) return self.type_node;
@ -176,7 +174,7 @@ pub const NodeBlock = struct {
end_token: Token,
statements: ArrayList(&Node),
pub fn iterate(self: &NodeBlock, index: usize) -> ?&Node {
pub fn iterate(self: &NodeBlock, index: usize) ?&Node {
var i = index;
if (i < self.statements.len) return self.statements.items[i];
@ -198,7 +196,7 @@ pub const NodeInfixOp = struct {
BangEqual,
};
pub fn iterate(self: &NodeInfixOp, index: usize) -> ?&Node {
pub fn iterate(self: &NodeInfixOp, index: usize) ?&Node {
var i = index;
if (i < 1) return self.lhs;
@ -234,7 +232,7 @@ pub const NodePrefixOp = struct {
volatile_token: ?Token,
};
pub fn iterate(self: &NodePrefixOp, index: usize) -> ?&Node {
pub fn iterate(self: &NodePrefixOp, index: usize) ?&Node {
var i = index;
switch (self.op) {
@ -258,7 +256,7 @@ pub const NodeIntegerLiteral = struct {
base: Node,
token: Token,
pub fn iterate(self: &NodeIntegerLiteral, index: usize) -> ?&Node {
pub fn iterate(self: &NodeIntegerLiteral, index: usize) ?&Node {
return null;
}
};
@ -267,7 +265,7 @@ pub const NodeFloatLiteral = struct {
base: Node,
token: Token,
pub fn iterate(self: &NodeFloatLiteral, index: usize) -> ?&Node {
pub fn iterate(self: &NodeFloatLiteral, index: usize) ?&Node {
return null;
}
};

View File

@ -33,7 +33,7 @@ pub const Instruction = struct {
TypeOf,
ToPtrType,
PtrTypeChild,
SetDebugSafety,
SetRuntimeSafety,
SetFloatMode,
ArrayType,
SliceType,

View File

@ -7,7 +7,7 @@ pub const ModuleRef = removeNullability(c.LLVMModuleRef);
pub const ContextRef = removeNullability(c.LLVMContextRef);
pub const BuilderRef = removeNullability(c.LLVMBuilderRef);
fn removeNullability(comptime T: type) -> type {
fn removeNullability(comptime T: type) type {
comptime assert(@typeId(T) == builtin.TypeId.Nullable);
return T.Child;
}

View File

@ -20,7 +20,7 @@ error ZigInstallationNotFound;
const default_zig_cache_name = "zig-cache";
pub fn main() -> %void {
pub fn main() %void {
main2() catch |err| {
if (err != error.InvalidCommandLineArguments) {
warn("{}\n", @errorName(err));
@ -39,7 +39,7 @@ const Cmd = enum {
Targets,
};
fn badArgs(comptime format: []const u8, args: ...) -> error {
fn badArgs(comptime format: []const u8, args: ...) error {
var stderr = try io.getStdErr();
var stderr_stream_adapter = io.FileOutStream.init(&stderr);
const stderr_stream = &stderr_stream_adapter.stream;
@ -48,7 +48,7 @@ fn badArgs(comptime format: []const u8, args: ...) -> error {
return error.InvalidCommandLineArguments;
}
pub fn main2() -> %void {
pub fn main2() %void {
const allocator = std.heap.c_allocator;
const args = try os.argsAlloc(allocator);
@ -371,7 +371,7 @@ pub fn main2() -> %void {
defer allocator.free(full_cache_dir);
const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix);
%defer allocator.free(zig_lib_dir);
errdefer allocator.free(zig_lib_dir);
const module = try Module.create(allocator, root_name, zig_root_source_file,
Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir);
@ -472,7 +472,7 @@ pub fn main2() -> %void {
}
}
fn printUsage(stream: &io.OutStream) -> %void {
fn printUsage(stream: &io.OutStream) %void {
try stream.write(
\\Usage: zig [command] [options]
\\
@ -548,7 +548,7 @@ fn printUsage(stream: &io.OutStream) -> %void {
);
}
fn printZen() -> %void {
fn printZen() %void {
var stdout_file = try io.getStdErr();
try stdout_file.write(
\\
@ -569,7 +569,7 @@ fn printZen() -> %void {
}
/// Caller must free result
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) -> %[]u8 {
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) %[]u8 {
if (zig_install_prefix_arg) |zig_install_prefix| {
return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {
warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err));
@ -585,9 +585,9 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const
}
/// Caller must free result
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 {
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8 {
const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig");
%defer allocator.free(test_zig_dir);
errdefer allocator.free(test_zig_dir);
const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig");
defer allocator.free(test_index_file);
@ -599,7 +599,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]
}
/// Caller must free result
fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 {
fn findZigLibDir(allocator: &mem.Allocator) %[]u8 {
const self_exe_path = try os.selfExeDirPath(allocator);
defer allocator.free(self_exe_path);

View File

@ -110,22 +110,22 @@ pub const Module = struct {
};
pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target,
kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) -> %&Module
kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) %&Module
{
var name_buffer = try Buffer.init(allocator, name);
%defer name_buffer.deinit();
errdefer name_buffer.deinit();
const context = c.LLVMContextCreate() ?? return error.OutOfMemory;
%defer c.LLVMContextDispose(context);
errdefer c.LLVMContextDispose(context);
const module = c.LLVMModuleCreateWithNameInContext(name_buffer.ptr(), context) ?? return error.OutOfMemory;
%defer c.LLVMDisposeModule(module);
errdefer c.LLVMDisposeModule(module);
const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory;
%defer c.LLVMDisposeBuilder(builder);
errdefer c.LLVMDisposeBuilder(builder);
const module_ptr = try allocator.create(Module);
%defer allocator.destroy(module_ptr);
errdefer allocator.destroy(module_ptr);
*module_ptr = Module {
.allocator = allocator,
@ -185,11 +185,11 @@ pub const Module = struct {
return module_ptr;
}
fn dump(self: &Module) {
fn dump(self: &Module) void {
c.LLVMDumpModule(self.module);
}
pub fn destroy(self: &Module) {
pub fn destroy(self: &Module) void {
c.LLVMDisposeBuilder(self.builder);
c.LLVMDisposeModule(self.module);
c.LLVMContextDispose(self.context);
@ -198,7 +198,7 @@ pub const Module = struct {
self.allocator.destroy(self);
}
pub fn build(self: &Module) -> %void {
pub fn build(self: &Module) %void {
if (self.llvm_argv.len != 0) {
var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
[][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
@ -211,13 +211,13 @@ pub const Module = struct {
try printError("unable to get real path '{}': {}", root_src_path, err);
return err;
};
%defer self.allocator.free(root_src_real_path);
errdefer self.allocator.free(root_src_real_path);
const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| {
try printError("unable to open '{}': {}", root_src_real_path, err);
return err;
};
%defer self.allocator.free(source_code);
errdefer self.allocator.free(source_code);
source_code[source_code.len - 3] = '\n';
source_code[source_code.len - 2] = '\n';
source_code[source_code.len - 1] = '\n';
@ -244,16 +244,16 @@ pub const Module = struct {
var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path);
defer parser.deinit();
const root_node = try parser.parse();
defer parser.freeAst(root_node);
const tree = try parser.parse();
defer tree.deinit();
var stderr_file = try std.io.getStdErr();
var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
const out_stream = &stderr_file_out_stream.stream;
try parser.renderAst(out_stream, root_node);
try parser.renderAst(out_stream, tree.root_node);
warn("====fmt:====\n");
try parser.renderSource(out_stream, root_node);
try parser.renderSource(out_stream, tree.root_node);
warn("====ir:====\n");
warn("TODO\n\n");
@ -263,11 +263,11 @@ pub const Module = struct {
}
pub fn link(self: &Module, out_file: ?[]const u8) -> %void {
pub fn link(self: &Module, out_file: ?[]const u8) %void {
warn("TODO link");
}
pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) -> %&LinkLib {
pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) %&LinkLib {
const is_libc = mem.eql(u8, name, "c");
if (is_libc) {
@ -297,7 +297,7 @@ pub const Module = struct {
}
};
fn printError(comptime format: []const u8, args: ...) -> %void {
fn printError(comptime format: []const u8, args: ...) %void {
var stderr_file = try std.io.getStdErr();
var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
const out_stream = &stderr_file_out_stream.stream;

View File

@ -20,14 +20,25 @@ pub const Parser = struct {
put_back_tokens: [2]Token,
put_back_count: usize,
source_file_name: []const u8,
cleanup_root_node: ?&ast.NodeRoot,
pub const Tree = struct {
root_node: &ast.NodeRoot,
pub fn deinit(self: &const Tree) void {
// TODO free the whole arena
}
};
// This memory contents are used only during a function call. It's used to repurpose memory;
// specifically so that freeAst can be guaranteed to succeed.
// we reuse the same bytes for the stack data structure used by parsing, tree rendering, and
// source rendering.
const utility_bytes_align = @alignOf( union { a: RenderAstFrame, b: State, c: RenderState } );
utility_bytes: []align(utility_bytes_align) u8,
pub fn init(tokenizer: &Tokenizer, allocator: &mem.Allocator, source_file_name: []const u8) -> Parser {
/// `allocator` should be an arena allocator. Parser never calls free on anything. After you're
/// done with a Parser, free the arena. After the arena is freed, no member functions of Parser
/// may be called.
pub fn init(tokenizer: &Tokenizer, allocator: &mem.Allocator, source_file_name: []const u8) Parser {
return Parser {
.allocator = allocator,
.tokenizer = tokenizer,
@ -35,12 +46,10 @@ pub const Parser = struct {
.put_back_count = 0,
.source_file_name = source_file_name,
.utility_bytes = []align(utility_bytes_align) u8{},
.cleanup_root_node = null,
};
}
pub fn deinit(self: &Parser) {
assert(self.cleanup_root_node == null);
pub fn deinit(self: &Parser) void {
self.allocator.free(self.utility_bytes);
}
@ -54,7 +63,7 @@ pub const Parser = struct {
NullableField: &?&ast.Node,
List: &ArrayList(&ast.Node),
pub fn store(self: &const DestPtr, value: &ast.Node) -> %void {
pub fn store(self: &const DestPtr, value: &ast.Node) %void {
switch (*self) {
DestPtr.Field => |ptr| *ptr = value,
DestPtr.NullableField => |ptr| *ptr = value,
@ -88,52 +97,16 @@ pub const Parser = struct {
Statement: &ast.NodeBlock,
};
pub fn freeAst(self: &Parser, root_node: &ast.NodeRoot) {
// utility_bytes is big enough to do this iteration since we were able to do
// the parsing in the first place
comptime assert(@sizeOf(State) >= @sizeOf(&ast.Node));
var stack = self.initUtilityArrayList(&ast.Node);
defer self.deinitUtilityArrayList(stack);
stack.append(&root_node.base) catch unreachable;
while (stack.popOrNull()) |node| {
var i: usize = 0;
while (node.iterate(i)) |child| : (i += 1) {
if (child.iterate(0) != null) {
stack.append(child) catch unreachable;
} else {
child.destroy(self.allocator);
}
}
node.destroy(self.allocator);
}
}
pub fn parse(self: &Parser) -> %&ast.NodeRoot {
const result = self.parseInner() catch |err| x: {
if (self.cleanup_root_node) |root_node| {
self.freeAst(root_node);
}
break :x err;
};
self.cleanup_root_node = null;
return result;
}
pub fn parseInner(self: &Parser) -> %&ast.NodeRoot {
/// Returns an AST tree, allocated with the parser's allocator.
/// Result should be freed with `freeAst` when done.
pub fn parse(self: &Parser) %Tree {
var stack = self.initUtilityArrayList(State);
defer self.deinitUtilityArrayList(stack);
const root_node = x: {
const root_node = try self.createRoot();
%defer self.allocator.destroy(root_node);
// This stack append has to succeed for freeAst to work
try stack.append(State.TopLevel);
break :x root_node;
};
assert(self.cleanup_root_node == null);
self.cleanup_root_node = root_node;
const root_node = try self.createRoot();
// TODO errdefer arena free root node
try stack.append(State.TopLevel);
while (true) {
//{
@ -159,7 +132,7 @@ pub const Parser = struct {
stack.append(State { .TopLevelExtern = token }) catch unreachable;
continue;
},
Token.Id.Eof => return root_node,
Token.Id.Eof => return Tree {.root_node = root_node},
else => {
self.putBackToken(token);
// TODO shouldn't need this cast
@ -211,7 +184,7 @@ pub const Parser = struct {
Token.Id.StringLiteral => {
@panic("TODO extern with string literal");
},
Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
stack.append(State.TopLevel) catch unreachable;
const fn_token = try self.eatToken(Token.Id.Keyword_fn);
// TODO shouldn't need this cast
@ -439,15 +412,11 @@ pub const Parser = struct {
if (token.id == Token.Id.Keyword_align) {
@panic("TODO fn proto align");
}
if (token.id == Token.Id.Arrow) {
stack.append(State {
.TypeExpr = DestPtr {.NullableField = &fn_proto.return_type},
}) catch unreachable;
continue;
} else {
self.putBackToken(token);
continue;
}
self.putBackToken(token);
stack.append(State {
.TypeExpr = DestPtr {.Field = &fn_proto.return_type},
}) catch unreachable;
continue;
},
State.ParamDecl => |fn_proto| {
@ -575,9 +544,8 @@ pub const Parser = struct {
}
}
fn createRoot(self: &Parser) -> %&ast.NodeRoot {
fn createRoot(self: &Parser) %&ast.NodeRoot {
const node = try self.allocator.create(ast.NodeRoot);
%defer self.allocator.destroy(node);
*node = ast.NodeRoot {
.base = ast.Node {.id = ast.Node.Id.Root},
@ -587,10 +555,9 @@ pub const Parser = struct {
}
fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
extern_token: &const ?Token) -> %&ast.NodeVarDecl
extern_token: &const ?Token) %&ast.NodeVarDecl
{
const node = try self.allocator.create(ast.NodeVarDecl);
%defer self.allocator.destroy(node);
*node = ast.NodeVarDecl {
.base = ast.Node {.id = ast.Node.Id.VarDecl},
@ -610,10 +577,9 @@ pub const Parser = struct {
}
fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token,
cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&ast.NodeFnProto
cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) %&ast.NodeFnProto
{
const node = try self.allocator.create(ast.NodeFnProto);
%defer self.allocator.destroy(node);
*node = ast.NodeFnProto {
.base = ast.Node {.id = ast.Node.Id.FnProto},
@ -621,7 +587,7 @@ pub const Parser = struct {
.name_token = null,
.fn_token = *fn_token,
.params = ArrayList(&ast.Node).init(self.allocator),
.return_type = null,
.return_type = undefined,
.var_args_token = null,
.extern_token = *extern_token,
.inline_token = *inline_token,
@ -633,9 +599,8 @@ pub const Parser = struct {
return node;
}
fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl {
fn createParamDecl(self: &Parser) %&ast.NodeParamDecl {
const node = try self.allocator.create(ast.NodeParamDecl);
%defer self.allocator.destroy(node);
*node = ast.NodeParamDecl {
.base = ast.Node {.id = ast.Node.Id.ParamDecl},
@ -648,9 +613,8 @@ pub const Parser = struct {
return node;
}
fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock {
fn createBlock(self: &Parser, begin_token: &const Token) %&ast.NodeBlock {
const node = try self.allocator.create(ast.NodeBlock);
%defer self.allocator.destroy(node);
*node = ast.NodeBlock {
.base = ast.Node {.id = ast.Node.Id.Block},
@ -661,9 +625,8 @@ pub const Parser = struct {
return node;
}
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) -> %&ast.NodeInfixOp {
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) %&ast.NodeInfixOp {
const node = try self.allocator.create(ast.NodeInfixOp);
%defer self.allocator.destroy(node);
*node = ast.NodeInfixOp {
.base = ast.Node {.id = ast.Node.Id.InfixOp},
@ -675,9 +638,8 @@ pub const Parser = struct {
return node;
}
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) -> %&ast.NodePrefixOp {
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) %&ast.NodePrefixOp {
const node = try self.allocator.create(ast.NodePrefixOp);
%defer self.allocator.destroy(node);
*node = ast.NodePrefixOp {
.base = ast.Node {.id = ast.Node.Id.PrefixOp},
@ -688,9 +650,8 @@ pub const Parser = struct {
return node;
}
fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier {
fn createIdentifier(self: &Parser, name_token: &const Token) %&ast.NodeIdentifier {
const node = try self.allocator.create(ast.NodeIdentifier);
%defer self.allocator.destroy(node);
*node = ast.NodeIdentifier {
.base = ast.Node {.id = ast.Node.Id.Identifier},
@ -699,9 +660,8 @@ pub const Parser = struct {
return node;
}
fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral {
fn createIntegerLiteral(self: &Parser, token: &const Token) %&ast.NodeIntegerLiteral {
const node = try self.allocator.create(ast.NodeIntegerLiteral);
%defer self.allocator.destroy(node);
*node = ast.NodeIntegerLiteral {
.base = ast.Node {.id = ast.Node.Id.IntegerLiteral},
@ -710,9 +670,8 @@ pub const Parser = struct {
return node;
}
fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral {
fn createFloatLiteral(self: &Parser, token: &const Token) %&ast.NodeFloatLiteral {
const node = try self.allocator.create(ast.NodeFloatLiteral);
%defer self.allocator.destroy(node);
*node = ast.NodeFloatLiteral {
.base = ast.Node {.id = ast.Node.Id.FloatLiteral},
@ -721,40 +680,36 @@ pub const Parser = struct {
return node;
}
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) -> %&ast.NodeIdentifier {
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) %&ast.NodeIdentifier {
const node = try self.createIdentifier(name_token);
%defer self.allocator.destroy(node);
try dest_ptr.store(&node.base);
return node;
}
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl {
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) %&ast.NodeParamDecl {
const node = try self.createParamDecl();
%defer self.allocator.destroy(node);
try list.append(&node.base);
return node;
}
fn createAttachFnProto(self: &Parser, list: &ArrayList(&ast.Node), fn_token: &const Token,
extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
inline_token: &const ?Token) -> %&ast.NodeFnProto
inline_token: &const ?Token) %&ast.NodeFnProto
{
const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
%defer self.allocator.destroy(node);
try list.append(&node.base);
return node;
}
fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token,
mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&ast.NodeVarDecl
mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) %&ast.NodeVarDecl
{
const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
%defer self.allocator.destroy(node);
try list.append(&node.base);
return node;
}
fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) -> error {
fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) error {
const loc = self.tokenizer.getTokenLocation(token);
warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
@ -775,24 +730,24 @@ pub const Parser = struct {
return error.ParseError;
}
fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) -> %void {
fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) %void {
if (token.id != id) {
return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
}
}
fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token {
fn eatToken(self: &Parser, id: @TagType(Token.Id)) %Token {
const token = self.getNextToken();
try self.expectToken(token, id);
return token;
}
fn putBackToken(self: &Parser, token: &const Token) {
fn putBackToken(self: &Parser, token: &const Token) void {
self.put_back_tokens[self.put_back_count] = *token;
self.put_back_count += 1;
}
fn getNextToken(self: &Parser) -> Token {
fn getNextToken(self: &Parser) Token {
if (self.put_back_count != 0) {
const put_back_index = self.put_back_count - 1;
const put_back_token = self.put_back_tokens[put_back_index];
@ -808,7 +763,7 @@ pub const Parser = struct {
indent: usize,
};
pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) -> %void {
pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
var stack = self.initUtilityArrayList(RenderAstFrame);
defer self.deinitUtilityArrayList(stack);
@ -847,7 +802,7 @@ pub const Parser = struct {
Indent: usize,
};
pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) -> %void {
pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
var stack = self.initUtilityArrayList(RenderState);
defer self.deinitUtilityArrayList(stack);
@ -1039,14 +994,12 @@ pub const Parser = struct {
if (fn_proto.align_expr != null) {
@panic("TODO");
}
if (fn_proto.return_type) |return_type| {
try stream.print(" -> ");
if (fn_proto.body_node) |body_node| {
try stack.append(RenderState { .Expression = body_node});
try stack.append(RenderState { .Text = " "});
}
try stack.append(RenderState { .Expression = return_type});
try stream.print(" ");
if (fn_proto.body_node) |body_node| {
try stack.append(RenderState { .Expression = body_node});
try stack.append(RenderState { .Text = " "});
}
try stack.append(RenderState { .Expression = fn_proto.return_type});
},
RenderState.Statement => |base| {
switch (base.id) {
@ -1066,7 +1019,7 @@ pub const Parser = struct {
}
}
fn initUtilityArrayList(self: &Parser, comptime T: type) -> ArrayList(T) {
fn initUtilityArrayList(self: &Parser, comptime T: type) ArrayList(T) {
const new_byte_count = self.utility_bytes.len - self.utility_bytes.len % @sizeOf(T);
self.utility_bytes = self.allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);
const typed_slice = ([]T)(self.utility_bytes);
@ -1077,7 +1030,7 @@ pub const Parser = struct {
};
}
fn deinitUtilityArrayList(self: &Parser, list: var) {
fn deinitUtilityArrayList(self: &Parser, list: var) void {
self.utility_bytes = ([]align(utility_bytes_align) u8)(list.items);
}
@ -1085,7 +1038,7 @@ pub const Parser = struct {
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
fn testParse(source: []const u8, allocator: &mem.Allocator) %[]u8 {
var padded_source: [0x100]u8 = undefined;
std.mem.copy(u8, padded_source[0..source.len], source);
padded_source[source.len + 0] = '\n';
@ -1096,30 +1049,34 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");
defer parser.deinit();
const root_node = try parser.parse();
defer parser.freeAst(root_node);
const tree = try parser.parse();
defer tree.deinit();
var buffer = try std.Buffer.initSize(allocator, 0);
var buffer_out_stream = io.BufferOutStream.init(&buffer);
try parser.renderSource(&buffer_out_stream.stream, root_node);
try parser.renderSource(&buffer_out_stream.stream, tree.root_node);
return buffer.toOwnedSlice();
}
error TestFailed;
error NondeterministicMemoryUsage;
error MemoryLeakDetected;
// TODO test for memory leaks
// TODO test for valid frees
fn testCanonical(source: []const u8) {
fn testCanonical(source: []const u8) %void {
const needed_alloc_count = x: {
// Try it once with unlimited memory, make sure it works
var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
const result_source = testParse(source, &failing_allocator.allocator) catch @panic("test failed");
const result_source = try testParse(source, &failing_allocator.allocator);
if (!mem.eql(u8, result_source, source)) {
warn("\n====== expected this output: =========\n");
warn("{}", source);
warn("\n======== instead found this: =========\n");
warn("{}", result_source);
warn("\n======================================\n");
@panic("test failed");
return error.TestFailed;
}
failing_allocator.allocator.free(result_source);
break :x failing_allocator.index;
@ -1130,7 +1087,7 @@ fn testCanonical(source: []const u8) {
var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
if (testParse(source, &failing_allocator.allocator)) |_| {
@panic("non-deterministic memory usage");
return error.NondeterministicMemoryUsage;
} else |err| {
assert(err == error.OutOfMemory);
// TODO make this pass
@ -1139,19 +1096,19 @@ fn testCanonical(source: []const u8) {
// fail_index, needed_alloc_count,
// failing_allocator.allocated_bytes, failing_allocator.freed_bytes,
// failing_allocator.index, failing_allocator.deallocations);
// @panic("memory leak detected");
// return error.MemoryLeakDetected;
//}
}
}
}
test "zig fmt" {
testCanonical(
\\extern fn puts(s: &const u8) -> c_int;
try testCanonical(
\\extern fn puts(s: &const u8) c_int;
\\
);
testCanonical(
try testCanonical(
\\const a = b;
\\pub const a = b;
\\var a = b;
@ -1163,44 +1120,44 @@ test "zig fmt" {
\\
);
testCanonical(
try testCanonical(
\\extern var foo: c_int;
\\
);
testCanonical(
try testCanonical(
\\var foo: c_int align(1);
\\
);
testCanonical(
\\fn main(argc: c_int, argv: &&u8) -> c_int {
try testCanonical(
\\fn main(argc: c_int, argv: &&u8) c_int {
\\ const a = b;
\\}
\\
);
testCanonical(
\\fn foo(argc: c_int, argv: &&u8) -> c_int {
try testCanonical(
\\fn foo(argc: c_int, argv: &&u8) c_int {
\\ return 0;
\\}
\\
);
testCanonical(
\\extern fn f1(s: &align(&u8) u8) -> c_int;
try testCanonical(
\\extern fn f1(s: &align(&u8) u8) c_int;
\\
);
testCanonical(
\\extern fn f1(s: &&align(1) &const &volatile u8) -> c_int;
\\extern fn f2(s: &align(1) const &align(1) volatile &const volatile u8) -> c_int;
\\extern fn f3(s: &align(1) const volatile u8) -> c_int;
try testCanonical(
\\extern fn f1(s: &&align(1) &const &volatile u8) c_int;
\\extern fn f2(s: &align(1) const &align(1) volatile &const volatile u8) c_int;
\\extern fn f3(s: &align(1) const volatile u8) c_int;
\\
);
testCanonical(
\\fn f1(a: bool, b: bool) -> bool {
try testCanonical(
\\fn f1(a: bool, b: bool) bool {
\\ a != b;
\\ return a == b;
\\}

View File

@ -11,7 +11,7 @@ pub const Target = union(enum) {
Native,
Cross: CrossTarget,
pub fn oFileExt(self: &const Target) -> []const u8 {
pub fn oFileExt(self: &const Target) []const u8 {
const environ = switch (*self) {
Target.Native => builtin.environ,
Target.Cross => |t| t.environ,
@ -22,28 +22,28 @@ pub const Target = union(enum) {
};
}
pub fn exeFileExt(self: &const Target) -> []const u8 {
pub fn exeFileExt(self: &const Target) []const u8 {
return switch (self.getOs()) {
builtin.Os.windows => ".exe",
else => "",
};
}
pub fn getOs(self: &const Target) -> builtin.Os {
pub fn getOs(self: &const Target) builtin.Os {
return switch (*self) {
Target.Native => builtin.os,
Target.Cross => |t| t.os,
};
}
pub fn isDarwin(self: &const Target) -> bool {
pub fn isDarwin(self: &const Target) bool {
return switch (self.getOs()) {
builtin.Os.ios, builtin.Os.macosx => true,
else => false,
};
}
pub fn isWindows(self: &const Target) -> bool {
pub fn isWindows(self: &const Target) bool {
return switch (self.getOs()) {
builtin.Os.windows => true,
else => false,
@ -51,7 +51,7 @@ pub const Target = union(enum) {
}
};
pub fn initializeAll() {
pub fn initializeAll() void {
c.LLVMInitializeAllTargets();
c.LLVMInitializeAllTargetInfos();
c.LLVMInitializeAllTargetMCs();

View File

@ -16,7 +16,6 @@ pub const Token = struct {
KeywordId{.bytes="and", .id = Id.Keyword_and},
KeywordId{.bytes="asm", .id = Id.Keyword_asm},
KeywordId{.bytes="break", .id = Id.Keyword_break},
KeywordId{.bytes="coldcc", .id = Id.Keyword_coldcc},
KeywordId{.bytes="comptime", .id = Id.Keyword_comptime},
KeywordId{.bytes="const", .id = Id.Keyword_const},
KeywordId{.bytes="continue", .id = Id.Keyword_continue},
@ -54,7 +53,7 @@ pub const Token = struct {
KeywordId{.bytes="while", .id = Id.Keyword_while},
};
fn getKeyword(bytes: []const u8) -> ?Id {
fn getKeyword(bytes: []const u8) ?Id {
for (keywords) |kw| {
if (mem.eql(u8, kw.bytes, bytes)) {
return kw.id;
@ -97,7 +96,6 @@ pub const Token = struct {
Keyword_and,
Keyword_asm,
Keyword_break,
Keyword_coldcc,
Keyword_comptime,
Keyword_const,
Keyword_continue,
@ -148,7 +146,7 @@ pub const Tokenizer = struct {
line_end: usize,
};
pub fn getTokenLocation(self: &Tokenizer, token: &const Token) -> Location {
pub fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
var loc = Location {
.line = 0,
.column = 0,
@ -173,13 +171,13 @@ pub const Tokenizer = struct {
}
/// For debugging purposes
pub fn dump(self: &Tokenizer, token: &const Token) {
pub fn dump(self: &Tokenizer, token: &const Token) void {
std.debug.warn("{} \"{}\"\n", @tagName(token.id), self.buffer[token.start..token.end]);
}
/// buffer must end with "\n\n\n". This is so that attempting to decode
/// a the 3 trailing bytes of a 4-byte utf8 sequence is never a buffer overflow.
pub fn init(buffer: []const u8) -> Tokenizer {
pub fn init(buffer: []const u8) Tokenizer {
std.debug.assert(buffer[buffer.len - 1] == '\n');
std.debug.assert(buffer[buffer.len - 2] == '\n');
std.debug.assert(buffer[buffer.len - 3] == '\n');
@ -214,7 +212,7 @@ pub const Tokenizer = struct {
Period2,
};
pub fn next(self: &Tokenizer) -> Token {
pub fn next(self: &Tokenizer) Token {
if (self.pending_invalid_token) |token| {
self.pending_invalid_token = null;
return token;
@ -530,11 +528,11 @@ pub const Tokenizer = struct {
return result;
}
pub fn getTokenSlice(self: &const Tokenizer, token: &const Token) -> []const u8 {
pub fn getTokenSlice(self: &const Tokenizer, token: &const Token) []const u8 {
return self.buffer[token.start..token.end];
}
fn checkLiteralCharacter(self: &Tokenizer) {
fn checkLiteralCharacter(self: &Tokenizer) void {
if (self.pending_invalid_token != null) return;
const invalid_length = self.getInvalidCharacterLength();
if (invalid_length == 0) return;
@ -545,7 +543,7 @@ pub const Tokenizer = struct {
};
}
fn getInvalidCharacterLength(self: &Tokenizer) -> u3 {
fn getInvalidCharacterLength(self: &Tokenizer) u3 {
const c0 = self.buffer[self.index];
if (c0 < 0x80) {
if (c0 < 0x20 or c0 == 0x7f) {
@ -638,7 +636,7 @@ test "tokenizer - illegal unicode codepoints" {
testTokenize("//\xe2\x80\xaa", []Token.Id{});
}
fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) {
fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
// (test authors, just make this bigger if you need it)
var padded_source: [0x100]u8 = undefined;
std.mem.copy(u8, padded_source[0..source.len], source);

View File

@ -1108,6 +1108,7 @@ struct TypeTableEntry {
bool zero_bits;
bool is_copyable;
bool gen_h_loop_flag;
union {
TypeTableEntryPointer pointer;
@ -1204,6 +1205,9 @@ struct FnTableEntry {
AstNode *set_alignstack_node;
uint32_t alignstack_value;
AstNode *set_cold_node;
bool is_cold;
ZigList<FnExport> export_list;
bool calls_errorable_function;
};
@ -1250,7 +1254,8 @@ enum BuiltinFnId {
BuiltinFnIdMod,
BuiltinFnIdTruncate,
BuiltinFnIdIntType,
BuiltinFnIdSetDebugSafety,
BuiltinFnIdSetCold,
BuiltinFnIdSetRuntimeSafety,
BuiltinFnIdSetFloatMode,
BuiltinFnIdTypeName,
BuiltinFnIdCanImplicitCast,
@ -1830,7 +1835,8 @@ enum IrInstructionId {
IrInstructionIdTypeOf,
IrInstructionIdToPtrType,
IrInstructionIdPtrTypeChild,
IrInstructionIdSetDebugSafety,
IrInstructionIdSetCold,
IrInstructionIdSetRuntimeSafety,
IrInstructionIdSetFloatMode,
IrInstructionIdArrayType,
IrInstructionIdSliceType,
@ -2202,11 +2208,16 @@ struct IrInstructionPtrTypeChild {
IrInstruction *value;
};
struct IrInstructionSetDebugSafety {
struct IrInstructionSetCold {
IrInstruction base;
IrInstruction *scope_value;
IrInstruction *debug_safety_on;
IrInstruction *is_cold;
};
struct IrInstructionSetRuntimeSafety {
IrInstruction base;
IrInstruction *safety_on;
};
struct IrInstructionSetFloatMode {

View File

@ -609,7 +609,10 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
buf_resize(&entry->name, 0);
buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name));
if (!entry->zero_bits) {
if (entry->zero_bits) {
entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, 0,
0, child_type->di_type, 0);
} else {
entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref,
(unsigned int)array_size) : nullptr;
@ -915,9 +918,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
if (fn_type_id->alignment != 0) {
buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
}
if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {
buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));
}
buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type;
// next, loop over the parameters again and compute debug information
@ -1079,7 +1080,7 @@ TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
const char *comma_str = (i == 0) ? "" : ",";
buf_appendf(&fn_type->name, "%svar", comma_str);
}
buf_appendf(&fn_type->name, ")->var");
buf_appendf(&fn_type->name, ")var");
fn_type->data.fn.fn_type_id = *fn_type_id;
fn_type->data.fn.is_generic = true;
@ -1155,6 +1156,104 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
return true;
}
static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
zig_unreachable();
case TypeTableEntryIdMetaType:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
return false;
case TypeTableEntryIdVoid:
case TypeTableEntryIdBool:
case TypeTableEntryIdInt:
case TypeTableEntryIdFloat:
case TypeTableEntryIdPointer:
case TypeTableEntryIdArray:
case TypeTableEntryIdFn:
return true;
case TypeTableEntryIdStruct:
return type_entry->data.structure.layout == ContainerLayoutPacked;
case TypeTableEntryIdUnion:
return type_entry->data.unionation.layout == ContainerLayoutPacked;
case TypeTableEntryIdMaybe:
{
TypeTableEntry *child_type = type_entry->data.maybe.child_type;
return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
}
case TypeTableEntryIdEnum:
return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
}
zig_unreachable();
}
static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
zig_unreachable();
case TypeTableEntryIdMetaType:
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
return false;
case TypeTableEntryIdOpaque:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdVoid:
case TypeTableEntryIdBool:
return true;
case TypeTableEntryIdInt:
switch (type_entry->data.integral.bit_count) {
case 8:
case 16:
case 32:
case 64:
case 128:
return true;
default:
return false;
}
case TypeTableEntryIdFloat:
return true;
case TypeTableEntryIdArray:
return type_allowed_in_extern(g, type_entry->data.array.child_type);
case TypeTableEntryIdFn:
return type_entry->data.fn.fn_type_id.cc == CallingConventionC;
case TypeTableEntryIdPointer:
return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
case TypeTableEntryIdStruct:
return type_entry->data.structure.layout == ContainerLayoutExtern;
case TypeTableEntryIdMaybe:
{
TypeTableEntry *child_type = type_entry->data.maybe.child_type;
return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
}
case TypeTableEntryIdEnum:
return type_entry->data.enumeration.layout == ContainerLayoutExtern;
case TypeTableEntryIdUnion:
return type_entry->data.unionation.layout == ContainerLayoutExtern;
}
zig_unreachable();
}
static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {
assert(proto_node->type == NodeTypeFnProto);
AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
@ -1205,6 +1304,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
}
}
if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, type_entry)) {
add_node_error(g, param_node->data.param_decl.type,
buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'",
buf_ptr(&type_entry->name),
calling_convention_name(fn_type_id.cc)));
return g->builtin_types.entry_invalid;
}
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
return g->builtin_types.entry_invalid;
@ -1269,6 +1376,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
fn_type_id.return_type = (fn_proto->return_type == nullptr) ?
g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);
if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
add_node_error(g, fn_proto->return_type,
buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
buf_ptr(&fn_type_id.return_type->name),
calling_convention_name(fn_type_id.cc)));
return g->builtin_types.entry_invalid;
}
switch (fn_type_id.return_type->id) {
case TypeTableEntryIdInvalid:
return g->builtin_types.entry_invalid;
@ -1421,46 +1536,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
enum_type->di_type = tag_di_type;
}
static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
zig_unreachable();
case TypeTableEntryIdMetaType:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
return false;
case TypeTableEntryIdVoid:
case TypeTableEntryIdBool:
case TypeTableEntryIdInt:
case TypeTableEntryIdFloat:
case TypeTableEntryIdPointer:
case TypeTableEntryIdArray:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
return true;
case TypeTableEntryIdStruct:
return type_entry->data.structure.layout == ContainerLayoutPacked;
case TypeTableEntryIdMaybe:
{
TypeTableEntry *child_type = type_entry->data.maybe.child_type;
return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
}
case TypeTableEntryIdEnum:
return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
}
zig_unreachable();
}
TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
TypeTableEntry *field_types[], size_t field_count)
@ -1864,7 +1939,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
TypeTableEntry *tag_type = union_type->data.unionation.tag_type;
if (tag_type == nullptr) {
if (tag_type == nullptr || tag_type->zero_bits) {
assert(most_aligned_union_member != nullptr);
if (padding_in_bits > 0) {
@ -2506,8 +2581,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
if (create_enum_type) {
ImportTableEntry *import = get_scope_import(scope);
uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
uint64_t tag_debug_size_in_bits = tag_type->zero_bits ? 0 :
8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
uint64_t tag_debug_align_in_bits = tag_type->zero_bits ? 0 :
8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
// TODO get a more accurate debug scope
ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name),
@ -2586,7 +2663,7 @@ static bool scope_is_root_decls(Scope *scope) {
static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) {
add_node_error(g, proto_node,
buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) -> unreachable', found '%s'",
buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) unreachable', found '%s'",
buf_ptr(&fn_type->name)));
}
@ -3448,7 +3525,6 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {
TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
assert(type_entry->id == TypeTableEntryIdUnion);
assert(type_entry->data.unionation.zero_bits_known);
assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX);
for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
TypeUnionField *field = &type_entry->data.unionation.fields[i];
if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {

View File

@ -92,7 +92,7 @@ static const char *return_string(ReturnKind kind) {
static const char *defer_string(ReturnKind kind) {
switch (kind) {
case ReturnKindUnconditional: return "defer";
case ReturnKindError: return "%defer";
case ReturnKindError: return "errdefer";
}
zig_unreachable();
}
@ -450,10 +450,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
}
AstNode *return_type_node = node->data.fn_proto.return_type;
if (return_type_node != nullptr) {
fprintf(ar->f, " -> ");
render_node_grouped(ar, return_type_node);
}
assert(return_type_node != nullptr);
fprintf(ar->f, " ");
render_node_grouped(ar, return_type_node);
break;
}
case NodeTypeFnDef:

View File

@ -485,11 +485,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
addLLVMFnAttr(fn_table_entry->llvm_value, "naked");
} else {
LLVMSetFunctionCallConv(fn_table_entry->llvm_value, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc));
if (fn_type->data.fn.fn_type_id.cc == CallingConventionCold) {
ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
}
}
bool want_cold = fn_table_entry->is_cold || fn_type->data.fn.fn_type_id.cc == CallingConventionCold;
if (want_cold) {
ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
}
LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage));
if (linkage == GlobalLinkageIdInternal) {
@ -803,7 +806,7 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
return true;
}
static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
if (g->build_mode == BuildModeFastRelease)
return false;
@ -898,7 +901,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
LLVMBuildUnreachable(g->builder);
}
static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {
static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
}
@ -1137,7 +1140,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
return fn_val;
}
static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
LLVMValueRef err_ret_trace_val = g->cur_err_ret_trace_val;
if (err_ret_trace_val == nullptr) {
@ -1176,7 +1179,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);
LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);
gen_debug_safety_crash(g, PanicMsgIdBoundsCheckFailure);
gen_safety_crash(g, PanicMsgIdBoundsCheckFailure);
if (upper_value) {
LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);
@ -1187,7 +1190,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, TypeTableEntry *actual_type,
static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, TypeTableEntry *actual_type,
TypeTableEntry *wanted_type, LLVMValueRef expr_val)
{
assert(actual_type->id == wanted_type->id);
@ -1206,7 +1209,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&
!wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
want_debug_safety)
want_runtime_safety)
{
LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");
@ -1216,7 +1219,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -1240,7 +1243,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
} else if (actual_type->id == TypeTableEntryIdInt) {
LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
if (!want_debug_safety) {
if (!want_runtime_safety) {
return trunc_val;
}
LLVMValueRef orig_val;
@ -1255,7 +1258,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdCastTruncatedData);
gen_safety_crash(g, PanicMsgIdCastTruncatedData);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
return trunc_val;
@ -1283,7 +1286,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS
LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);
gen_safety_crash(g, PanicMsgIdIntegerOverflow);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
return result;
@ -1491,7 +1494,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdShlOverflowedBits);
gen_safety_crash(g, PanicMsgIdShlOverflowedBits);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
return result;
@ -1516,7 +1519,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry,
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdShrOverflowedBits);
gen_safety_crash(g, PanicMsgIdShrOverflowedBits);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
return result;
@ -1562,14 +1565,14 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
}
}
static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_math,
static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
LLVMValueRef val1, LLVMValueRef val2,
TypeTableEntry *type_entry, DivKind div_kind)
{
ZigLLVMSetFastMath(g->builder, want_fast_math);
LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
if (want_debug_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) {
if (want_runtime_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) {
LLVMValueRef is_zero_bit;
if (type_entry->id == TypeTableEntryIdInt) {
is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
@ -1583,7 +1586,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
LLVMBuildCondBr(g->builder, is_zero_bit, div_zero_fail_block, div_zero_ok_block);
LLVMPositionBuilderAtEnd(g->builder, div_zero_fail_block);
gen_debug_safety_crash(g, PanicMsgIdDivisionByZero);
gen_safety_crash(g, PanicMsgIdDivisionByZero);
LLVMPositionBuilderAtEnd(g->builder, div_zero_ok_block);
@ -1600,7 +1603,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);
LLVMPositionBuilderAtEnd(g->builder, overflow_fail_block);
gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);
gen_safety_crash(g, PanicMsgIdIntegerOverflow);
LLVMPositionBuilderAtEnd(g->builder, overflow_ok_block);
}
@ -1612,7 +1615,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
case DivKindFloat:
return result;
case DivKindExact:
if (want_debug_safety) {
if (want_runtime_safety) {
LLVMValueRef floored = gen_floor(g, result, type_entry);
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
@ -1621,7 +1624,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);
gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -1669,7 +1672,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
return LLVMBuildUDiv(g->builder, val1, val2, "");
}
case DivKindExact:
if (want_debug_safety) {
if (want_runtime_safety) {
LLVMValueRef remainder_val;
if (type_entry->data.integral.is_signed) {
remainder_val = LLVMBuildSRem(g->builder, val1, val2, "");
@ -1683,7 +1686,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);
gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -1721,14 +1724,14 @@ enum RemKind {
RemKindMod,
};
static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_math,
static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
LLVMValueRef val1, LLVMValueRef val2,
TypeTableEntry *type_entry, RemKind rem_kind)
{
ZigLLVMSetFastMath(g->builder, want_fast_math);
LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
if (want_debug_safety) {
if (want_runtime_safety) {
LLVMValueRef is_zero_bit;
if (type_entry->id == TypeTableEntryIdInt) {
LLVMIntPredicate pred = type_entry->data.integral.is_signed ? LLVMIntSLE : LLVMIntEQ;
@ -1743,7 +1746,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_m
LLVMBuildCondBr(g->builder, is_zero_bit, rem_zero_fail_block, rem_zero_ok_block);
LLVMPositionBuilderAtEnd(g->builder, rem_zero_fail_block);
gen_debug_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
gen_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block);
}
@ -1789,8 +1792,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
op_id == IrBinOpBitShiftRightExact);
TypeTableEntry *type_entry = op1->value.type;
bool want_debug_safety = bin_op_instruction->safety_check_on &&
ir_want_debug_safety(g, &bin_op_instruction->base);
bool want_runtime_safety = bin_op_instruction->safety_check_on &&
ir_want_runtime_safety(g, &bin_op_instruction->base);
LLVMValueRef op1_value = ir_llvm_value(g, op1);
LLVMValueRef op2_value = ir_llvm_value(g, op2);
@ -1838,7 +1841,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
bool is_wrapping = (op_id == IrBinOpAddWrap);
if (is_wrapping) {
return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
} else if (want_runtime_safety) {
return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value);
} else if (type_entry->data.integral.is_signed) {
return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
@ -1863,7 +1866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy);
if (is_sloppy) {
return LLVMBuildShl(g->builder, op1_value, op2_casted, "");
} else if (want_debug_safety) {
} else if (want_runtime_safety) {
return gen_overflow_shl_op(g, type_entry, op1_value, op2_casted);
} else if (type_entry->data.integral.is_signed) {
return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, "");
@ -1884,7 +1887,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
} else {
return LLVMBuildLShr(g->builder, op1_value, op2_casted, "");
}
} else if (want_debug_safety) {
} else if (want_runtime_safety) {
return gen_overflow_shr_op(g, type_entry, op1_value, op2_casted);
} else if (type_entry->data.integral.is_signed) {
return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, "");
@ -1901,7 +1904,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
bool is_wrapping = (op_id == IrBinOpSubWrap);
if (is_wrapping) {
return LLVMBuildSub(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
} else if (want_runtime_safety) {
return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value);
} else if (type_entry->data.integral.is_signed) {
return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
@ -1920,7 +1923,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
bool is_wrapping = (op_id == IrBinOpMultWrap);
if (is_wrapping) {
return LLVMBuildMul(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
} else if (want_runtime_safety) {
return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value);
} else if (type_entry->data.integral.is_signed) {
return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
@ -1931,22 +1934,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
zig_unreachable();
}
case IrBinOpDivUnspecified:
return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, DivKindFloat);
case IrBinOpDivExact:
return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, DivKindExact);
case IrBinOpDivTrunc:
return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, DivKindTrunc);
case IrBinOpDivFloor:
return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, DivKindFloor);
case IrBinOpRemRem:
return gen_rem(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, RemKindRem);
case IrBinOpRemMod:
return gen_rem(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, RemKindMod);
}
zig_unreachable();
@ -2004,7 +2007,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
} else if (src_size == 1) {
LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
if (ir_want_debug_safety(g, &cast_instruction->base)) {
if (ir_want_runtime_safety(g, &cast_instruction->base)) {
LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
@ -2013,7 +2016,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdSliceWidenRemainder);
gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -2108,7 +2111,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
int_type = actual_type;
}
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base), int_type,
return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), int_type,
instruction->base.value.type, target_val);
}
@ -2130,7 +2133,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type;
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
instruction->target->value.type, tag_int_type, target_val);
}
@ -2144,7 +2147,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
if (ir_want_debug_safety(g, &instruction->base)) {
if (ir_want_runtime_safety(g, &instruction->base)) {
LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
LLVMValueRef ok_bit;
@ -2168,7 +2171,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);
gen_safety_crash(g, PanicMsgIdInvalidErrorCode);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -2185,11 +2188,11 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
if (actual_type->id == TypeTableEntryIdPureError) {
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
g->err_tag_type, wanted_type, target_val);
} else if (actual_type->id == TypeTableEntryIdErrorUnion) {
if (!type_has_bits(actual_type->data.error.child_type)) {
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
g->err_tag_type, wanted_type, target_val);
} else {
zig_panic("TODO");
@ -2202,8 +2205,8 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
IrInstructionUnreachable *unreachable_instruction)
{
if (ir_want_debug_safety(g, &unreachable_instruction->base)) {
gen_debug_safety_crash(g, PanicMsgIdUnreachable);
if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
gen_safety_crash(g, PanicMsgIdUnreachable);
} else {
LLVMBuildUnreachable(g->builder);
}
@ -2245,7 +2248,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
} else if (expr_type->id == TypeTableEntryIdInt) {
if (op_id == IrUnOpNegationWrap) {
return LLVMBuildNeg(g->builder, expr, "");
} else if (ir_want_debug_safety(g, &un_op_instruction->base)) {
} else if (ir_want_runtime_safety(g, &un_op_instruction->base)) {
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
return gen_overflow_op(g, expr_type, AddSubMulSub, zero, expr);
} else if (expr_type->data.integral.is_signed) {
@ -2314,7 +2317,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
var->align_bytes, 0, 0);
gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));
} else {
bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base);
if (want_safe) {
TypeTableEntry *usize = g->builtin_types.entry_usize;
uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);
@ -2406,7 +2409,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
if (!type_has_bits(array_type))
return nullptr;
bool safety_check_on = ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on;
bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on;
if (array_type->id == TypeTableEntryIdArray) {
if (safety_check_on) {
@ -2590,7 +2593,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
return bitcasted_union_field_ptr;
}
if (ir_want_debug_safety(g, &instruction->base)) {
if (ir_want_runtime_safety(g, &instruction->base)) {
LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
@ -2603,7 +2606,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);
LLVMPositionBuilderAtEnd(g->builder, bad_block);
gen_debug_safety_crash(g, PanicMsgIdBadUnionField);
gen_safety_crash(g, PanicMsgIdBadUnionField);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -2773,14 +2776,14 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
TypeTableEntry *child_type = maybe_type->data.maybe.child_type;
LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {
if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeFail");
LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
gen_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -2910,7 +2913,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
}
LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
if (ir_want_debug_safety(g, &instruction->base)) {
if (ir_want_runtime_safety(g, &instruction->base)) {
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));
LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);
add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);
@ -2932,7 +2935,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable
TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
if (ir_want_debug_safety(g, &instruction->base)) {
if (ir_want_runtime_safety(g, &instruction->base)) {
size_t field_count = enum_type->data.enumeration.src_field_count;
// if the field_count can't fit in the bits of the enum_type, then it can't possibly
@ -2985,8 +2988,8 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
assert(target_val);
bool want_debug_safety = ir_want_debug_safety(g, &instruction->base);
if (!want_debug_safety) {
bool want_runtime_safety = ir_want_runtime_safety(g, &instruction->base);
if (!want_runtime_safety) {
return target_val;
}
@ -3035,7 +3038,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdIncorrectAlignment);
gen_safety_crash(g, PanicMsgIdIncorrectAlignment);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
@ -3173,7 +3176,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
bool want_debug_safety = instruction->safety_check_on && ir_want_debug_safety(g, &instruction->base);
bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
if (array_type->id == TypeTableEntryIdArray) {
LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
@ -3184,7 +3187,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
end_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, array_type->data.array.len, false);
}
if (want_debug_safety) {
if (want_runtime_safety) {
add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
if (instruction->end) {
LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
@ -3195,7 +3198,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
if (!type_has_bits(array_type)) {
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
// TODO if debug safety is on, store 0xaaaaaaa in ptr field
// TODO if runtime safety is on, store 0xaaaaaaa in ptr field
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return tmp_struct_ptr;
@ -3219,7 +3222,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
LLVMValueRef end_val = ir_llvm_value(g, instruction->end);
if (want_debug_safety) {
if (want_runtime_safety) {
add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
}
@ -3243,7 +3246,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
assert(len_index != SIZE_MAX);
LLVMValueRef prev_end = nullptr;
if (!instruction->end || want_debug_safety) {
if (!instruction->end || want_runtime_safety) {
LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");
}
@ -3256,7 +3259,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
end_val = prev_end;
}
if (want_debug_safety) {
if (want_runtime_safety) {
assert(prev_end);
add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
if (instruction->end) {
@ -3429,7 +3432,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {
if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {
LLVMValueRef err_val;
if (type_has_bits(child_type)) {
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
@ -3444,7 +3447,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
LLVMPositionBuilderAtEnd(g->builder, err_block);
gen_debug_safety_crash_for_err(g, err_val);
gen_safety_crash_for_err(g, err_val);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -3656,7 +3659,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdToPtrType:
case IrInstructionIdPtrTypeChild:
case IrInstructionIdFieldPtr:
case IrInstructionIdSetDebugSafety:
case IrInstructionIdSetCold:
case IrInstructionIdSetRuntimeSafety:
case IrInstructionIdSetFloatMode:
case IrInstructionIdArrayType:
case IrInstructionIdSliceType:
@ -5233,7 +5237,8 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);
create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);
create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
@ -5788,7 +5793,76 @@ static const char *c_int_type_names[] = {
"unsigned long long",
};
static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
struct GenH {
ZigList<TypeTableEntry *> types_to_declare;
};
static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry) {
if (type_entry->gen_h_loop_flag)
return;
type_entry->gen_h_loop_flag = true;
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
case TypeTableEntryIdMetaType:
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
zig_unreachable();
case TypeTableEntryIdVoid:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdBool:
case TypeTableEntryIdInt:
case TypeTableEntryIdFloat:
return;
case TypeTableEntryIdOpaque:
gen_h->types_to_declare.append(type_entry);
return;
case TypeTableEntryIdStruct:
for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
TypeStructField *field = &type_entry->data.structure.fields[i];
prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
}
gen_h->types_to_declare.append(type_entry);
return;
case TypeTableEntryIdUnion:
for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
TypeUnionField *field = &type_entry->data.unionation.fields[i];
prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
}
gen_h->types_to_declare.append(type_entry);
return;
case TypeTableEntryIdEnum:
prepend_c_type_to_decl_list(g, gen_h, type_entry->data.enumeration.tag_int_type);
gen_h->types_to_declare.append(type_entry);
return;
case TypeTableEntryIdPointer:
prepend_c_type_to_decl_list(g, gen_h, type_entry->data.pointer.child_type);
return;
case TypeTableEntryIdArray:
prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type);
return;
case TypeTableEntryIdMaybe:
prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type);
return;
case TypeTableEntryIdFn:
for (size_t i = 0; i < type_entry->data.fn.fn_type_id.param_count; i += 1) {
prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.param_info[i].type);
}
prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.return_type);
return;
}
}
static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf *out_buf) {
assert(type_entry);
for (size_t i = 0; i < array_length(c_int_type_names); i += 1) {
@ -5816,6 +5890,8 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
return;
}
prepend_c_type_to_decl_list(g, gen_h, type_entry);
switch (type_entry->id) {
case TypeTableEntryIdVoid:
buf_init_from_str(out_buf, "void");
@ -5856,7 +5932,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
{
Buf child_buf = BUF_INIT;
TypeTableEntry *child_type = type_entry->data.pointer.child_type;
get_c_type(g, child_type, &child_buf);
get_c_type(g, gen_h, child_type, &child_buf);
const char *const_str = type_entry->data.pointer.is_const ? "const " : "";
buf_resize(out_buf, 0);
@ -5872,23 +5948,47 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
} else if (child_type->id == TypeTableEntryIdPointer ||
child_type->id == TypeTableEntryIdFn)
{
return get_c_type(g, child_type, out_buf);
return get_c_type(g, gen_h, child_type, out_buf);
} else {
zig_unreachable();
}
}
case TypeTableEntryIdStruct:
{
buf_init_from_str(out_buf, "struct ");
buf_append_buf(out_buf, &type_entry->name);
return;
}
case TypeTableEntryIdUnion:
{
buf_init_from_str(out_buf, "union ");
buf_append_buf(out_buf, &type_entry->name);
return;
}
case TypeTableEntryIdEnum:
{
buf_init_from_str(out_buf, "enum ");
buf_append_buf(out_buf, &type_entry->name);
return;
}
case TypeTableEntryIdOpaque:
{
// TODO add to table of structs we need to declare
buf_init_from_buf(out_buf, &type_entry->name);
return;
}
case TypeTableEntryIdArray:
{
TypeTableEntryArray *array_data = &type_entry->data.array;
Buf *child_buf = buf_alloc();
get_c_type(g, gen_h, array_data->child_type, child_buf);
buf_resize(out_buf, 0);
buf_appendf(out_buf, "%s", buf_ptr(child_buf));
return;
}
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
zig_panic("TODO implement get_c_type for more types");
case TypeTableEntryIdInvalid:
@ -5942,6 +6042,9 @@ static void gen_h_file(CodeGen *g) {
if (!g->want_h_file)
return;
GenH gen_h_data = {0};
GenH *gen_h = &gen_h_data;
codegen_add_time_event(g, "Generate .h");
assert(!g->is_test_build);
@ -5971,7 +6074,7 @@ static void gen_h_file(CodeGen *g) {
FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
Buf return_type_c = BUF_INIT;
get_c_type(g, fn_type_id->return_type, &return_type_c);
get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c);
buf_appendf(&h_buf, "%s %s %s(",
buf_ptr(export_macro),
@ -5987,9 +6090,16 @@ static void gen_h_file(CodeGen *g) {
const char *comma_str = (param_i == 0) ? "" : ", ";
const char *restrict_str = param_info->is_noalias ? "restrict" : "";
get_c_type(g, param_info->type, &param_type_c);
buf_appendf(&h_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c),
restrict_str, buf_ptr(param_name));
get_c_type(g, gen_h, param_info->type, &param_type_c);
if (param_info->type->id == TypeTableEntryIdArray) {
// Arrays decay to pointers
buf_appendf(&h_buf, "%s%s%s %s[]", comma_str, buf_ptr(&param_type_c),
restrict_str, buf_ptr(param_name));
} else {
buf_appendf(&h_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c),
restrict_str, buf_ptr(param_name));
}
}
buf_appendf(&h_buf, ")");
} else {
@ -6027,6 +6137,85 @@ static void gen_h_file(CodeGen *g) {
fprintf(out_h, "#endif\n");
fprintf(out_h, "\n");
for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {
TypeTableEntry *type_entry = gen_h->types_to_declare.at(type_i);
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
case TypeTableEntryIdMetaType:
case TypeTableEntryIdVoid:
case TypeTableEntryIdBool:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdInt:
case TypeTableEntryIdFloat:
case TypeTableEntryIdPointer:
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdArray:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdMaybe:
case TypeTableEntryIdFn:
zig_unreachable();
case TypeTableEntryIdEnum:
assert(type_entry->data.enumeration.layout == ContainerLayoutExtern);
fprintf(out_h, "enum %s {\n", buf_ptr(&type_entry->name));
for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) {
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
Buf *value_buf = buf_alloc();
bigint_append_buf(value_buf, &enum_field->value, 10);
fprintf(out_h, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf));
if (field_i != type_entry->data.enumeration.src_field_count - 1) {
fprintf(out_h, ",");
}
fprintf(out_h, "\n");
}
fprintf(out_h, "};\n\n");
break;
case TypeTableEntryIdStruct:
assert(type_entry->data.structure.layout == ContainerLayoutExtern);
fprintf(out_h, "struct %s {\n", buf_ptr(&type_entry->name));
for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];
Buf *type_name_buf = buf_alloc();
get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
if (struct_field->type_entry->id == TypeTableEntryIdArray) {
fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),
buf_ptr(struct_field->name),
struct_field->type_entry->data.array.len);
} else {
fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));
}
}
fprintf(out_h, "};\n\n");
break;
case TypeTableEntryIdUnion:
assert(type_entry->data.unionation.layout == ContainerLayoutExtern);
fprintf(out_h, "union %s {\n", buf_ptr(&type_entry->name));
for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {
TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
Buf *type_name_buf = buf_alloc();
get_c_type(g, gen_h, union_field->type_entry, type_name_buf);
fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name));
}
fprintf(out_h, "};\n\n");
break;
case TypeTableEntryIdOpaque:
fprintf(out_h, "struct %s;\n\n", buf_ptr(&type_entry->name));
break;
}
}
fprintf(out_h, "%s", buf_ptr(&h_buf));
fprintf(out_h, "\n#endif\n");

View File

@ -272,8 +272,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)
return IrInstructionIdPtrTypeChild;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {
return IrInstructionIdSetDebugSafety;
static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {
return IrInstructionIdSetCold;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) {
return IrInstructionIdSetRuntimeSafety;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) {
@ -1262,15 +1266,22 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN
return &instruction->base;
}
static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *scope_value, IrInstruction *debug_safety_on)
{
IrInstructionSetDebugSafety *instruction = ir_build_instruction<IrInstructionSetDebugSafety>(irb, scope, source_node);
instruction->scope_value = scope_value;
instruction->debug_safety_on = debug_safety_on;
static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) {
IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node);
instruction->is_cold = is_cold;
ir_ref_instruction(scope_value, irb->current_basic_block);
ir_ref_instruction(debug_safety_on, irb->current_basic_block);
ir_ref_instruction(is_cold, irb->current_basic_block);
return &instruction->base;
}
static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *safety_on)
{
IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node);
instruction->safety_on = safety_on;
ir_ref_instruction(safety_on, irb->current_basic_block);
return &instruction->base;
}
@ -3065,19 +3076,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return arg;
return ir_build_typeof(irb, scope, node, arg);
}
case BuiltinFnIdSetDebugSafety:
case BuiltinFnIdSetCold:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;
AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;
return ir_build_set_cold(irb, scope, node, arg0_value);
}
case BuiltinFnIdSetRuntimeSafety:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;
return ir_build_set_debug_safety(irb, scope, node, arg0_value, arg1_value);
return ir_build_set_runtime_safety(irb, scope, node, arg0_value);
}
case BuiltinFnIdSetFloatMode:
{
@ -4769,7 +4784,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
}
static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,
IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *target_value_ptr, IrInstruction *prong_value,
IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime,
IrInstruction *target_value_ptr, IrInstruction *prong_value,
ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values)
{
assert(switch_node->type == NodeTypeSwitchExpr);
@ -4786,7 +4802,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
bool is_shadowable = false;
bool is_const = true;
VariableTableEntry *var = ir_create_var(irb, var_symbol_node, scope,
var_name, is_const, is_const, is_shadowable, is_comptime);
var_name, is_const, is_const, is_shadowable, var_is_comptime);
child_scope = var->child_scope;
IrInstruction *var_value;
if (prong_value) {
@ -4827,10 +4843,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
ZigList<IrInstructionSwitchBrCase> cases = {0};
IrInstruction *is_comptime;
IrInstruction *var_is_comptime;
if (ir_should_inline(irb->exec, scope)) {
is_comptime = ir_build_const_bool(irb, scope, node, true);
var_is_comptime = is_comptime;
} else {
is_comptime = ir_build_test_comptime(irb, scope, node, target_value);
var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr);
}
ZigList<IrInstruction *> incoming_values = {0};
@ -4856,7 +4875,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
IrBasicBlock *prev_block = irb->current_basic_block;
ir_set_cursor_at_end_and_append_block(irb, else_block);
if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
{
return irb->codegen->invalid_instruction;
}
@ -4923,7 +4942,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
{
return irb->codegen->invalid_instruction;
}
@ -4967,7 +4986,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
IrBasicBlock *prev_block = irb->current_basic_block;
ir_set_cursor_at_end_and_append_block(irb, prong_block);
if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))
is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))
{
return irb->codegen->invalid_instruction;
}
@ -4992,7 +5011,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
ir_set_cursor_at_end_and_append_block(irb, end_block);
assert(incoming_blocks.length == incoming_values.length);
return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
if (incoming_blocks.length == 0) {
return ir_build_const_void(irb, scope, node);
} else {
return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
}
}
static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
@ -8816,6 +8839,13 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
if (op_id == IrBinOpBitShiftLeftLossy) {
op_id = IrBinOpBitShiftLeftExact;
}
if (casted_op2->value.data.x_bigint.is_negative) {
Buf *val_buf = buf_alloc();
bigint_append_buf(val_buf, &casted_op2->value.data.x_bigint, 10);
ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf)));
return ira->codegen->builtin_types.entry_invalid;
}
} else {
TypeTableEntry *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen,
op1->value.type->data.integral.bit_count - 1);
@ -9002,7 +9032,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
int err;
if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) {
if (err == ErrorDivByZero) {
ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("division by zero is undefined"));
ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("division by zero"));
return ira->codegen->builtin_types.entry_invalid;
} else if (err == ErrorOverflow) {
ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow"));
@ -11540,72 +11570,90 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
return ira->codegen->builtin_types.entry_type;
}
static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
IrInstructionSetDebugSafety *set_debug_safety_instruction)
{
IrInstruction *target_instruction = set_debug_safety_instruction->scope_value->other;
TypeTableEntry *target_type = target_instruction->value.type;
if (type_is_invalid(target_type))
return ira->codegen->builtin_types.entry_invalid;
ConstExprValue *target_val = ir_resolve_const(ira, target_instruction, UndefBad);
if (!target_val)
static TypeTableEntry *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) {
if (ira->new_irb.exec->is_inline) {
// ignore setCold when running functions at compile time
ir_build_const_from(ira, &instruction->base);
return ira->codegen->builtin_types.entry_void;
}
IrInstruction *is_cold_value = instruction->is_cold->other;
bool want_cold;
if (!ir_resolve_bool(ira, is_cold_value, &want_cold))
return ira->codegen->builtin_types.entry_invalid;
FnTableEntry *fn_entry = scope_fn_entry(instruction->base.scope);
if (fn_entry == nullptr) {
ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function"));
return ira->codegen->builtin_types.entry_invalid;
}
if (fn_entry->set_cold_node != nullptr) {
ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function"));
add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here"));
return ira->codegen->builtin_types.entry_invalid;
}
fn_entry->set_cold_node = instruction->base.source_node;
fn_entry->is_cold = want_cold;
ir_build_const_from(ira, &instruction->base);
return ira->codegen->builtin_types.entry_void;
}
static TypeTableEntry *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira,
IrInstructionSetRuntimeSafety *set_runtime_safety_instruction)
{
if (ira->new_irb.exec->is_inline) {
// ignore setDebugSafety when running functions at compile time
ir_build_const_from(ira, &set_debug_safety_instruction->base);
// ignore setRuntimeSafety when running functions at compile time
ir_build_const_from(ira, &set_runtime_safety_instruction->base);
return ira->codegen->builtin_types.entry_void;
}
bool *safety_off_ptr;
AstNode **safety_set_node_ptr;
if (target_type->id == TypeTableEntryIdBlock) {
ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block;
safety_off_ptr = &block_scope->safety_off;
safety_set_node_ptr = &block_scope->safety_set_node;
} else if (target_type->id == TypeTableEntryIdFn) {
FnTableEntry *target_fn = target_val->data.x_fn.fn_entry;
assert(target_fn->def_scope);
safety_off_ptr = &target_fn->def_scope->safety_off;
safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
} else if (target_type->id == TypeTableEntryIdMetaType) {
ScopeDecls *decls_scope;
TypeTableEntry *type_arg = target_val->data.x_type;
if (type_arg->id == TypeTableEntryIdStruct) {
decls_scope = type_arg->data.structure.decls_scope;
} else if (type_arg->id == TypeTableEntryIdEnum) {
decls_scope = type_arg->data.enumeration.decls_scope;
} else if (type_arg->id == TypeTableEntryIdUnion) {
decls_scope = type_arg->data.unionation.decls_scope;
Scope *scope = set_runtime_safety_instruction->base.scope;
while (scope != nullptr) {
if (scope->id == ScopeIdBlock) {
ScopeBlock *block_scope = (ScopeBlock *)scope;
safety_off_ptr = &block_scope->safety_off;
safety_set_node_ptr = &block_scope->safety_set_node;
break;
} else if (scope->id == ScopeIdFnDef) {
ScopeFnDef *def_scope = (ScopeFnDef *)scope;
FnTableEntry *target_fn = def_scope->fn_entry;
assert(target_fn->def_scope != nullptr);
safety_off_ptr = &target_fn->def_scope->safety_off;
safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
break;
} else if (scope->id == ScopeIdDecls) {
ScopeDecls *decls_scope = (ScopeDecls *)scope;
safety_off_ptr = &decls_scope->safety_off;
safety_set_node_ptr = &decls_scope->safety_set_node;
break;
} else {
ir_add_error_node(ira, target_instruction->source_node,
buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
return ira->codegen->builtin_types.entry_invalid;
scope = scope->parent;
continue;
}
safety_off_ptr = &decls_scope->safety_off;
safety_set_node_ptr = &decls_scope->safety_set_node;
} else {
ir_add_error_node(ira, target_instruction->source_node,
buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name)));
return ira->codegen->builtin_types.entry_invalid;
}
assert(scope != nullptr);
IrInstruction *debug_safety_on_value = set_debug_safety_instruction->debug_safety_on->other;
bool want_debug_safety;
if (!ir_resolve_bool(ira, debug_safety_on_value, &want_debug_safety))
IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->other;
bool want_runtime_safety;
if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety))
return ira->codegen->builtin_types.entry_invalid;
AstNode *source_node = set_debug_safety_instruction->base.source_node;
AstNode *source_node = set_runtime_safety_instruction->base.source_node;
if (*safety_set_node_ptr) {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("debug safety set twice for same scope"));
buf_sprintf("runtime safety set twice for same scope"));
add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here"));
return ira->codegen->builtin_types.entry_invalid;
}
*safety_set_node_ptr = source_node;
*safety_off_ptr = !want_debug_safety;
*safety_off_ptr = !want_runtime_safety;
ir_build_const_from(ira, &set_debug_safety_instruction->base);
ir_build_const_from(ira, &set_runtime_safety_instruction->base);
return ira->codegen->builtin_types.entry_void;
}
@ -12243,11 +12291,18 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
}
TypeTableEntry *tag_type = target_type->data.unionation.tag_type;
assert(tag_type != nullptr);
assert(tag_type->id == TypeTableEntryIdEnum);
if (pointee_val) {
ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_union.tag);
return tag_type;
}
if (tag_type->data.enumeration.src_field_count == 1) {
ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
TypeEnumField *only_field = &tag_type->data.enumeration.fields[0];
bigint_init_bigint(&out_val->data.x_enum_tag, &only_field->value);
return tag_type;
}
IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,
switch_target_instruction->base.source_node, target_value_ptr);
@ -14499,6 +14554,11 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
if (type_is_invalid(msg->value.type))
return ira->codegen->builtin_types.entry_invalid;
if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) {
ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time"));
return ira->codegen->builtin_types.entry_invalid;
}
TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
@ -15212,8 +15272,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
case IrInstructionIdPtrTypeChild:
return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
case IrInstructionIdSetDebugSafety:
return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
case IrInstructionIdSetCold:
return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);
case IrInstructionIdSetRuntimeSafety:
return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
case IrInstructionIdSetFloatMode:
return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
case IrInstructionIdSliceType:
@ -15448,7 +15510,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdCall:
case IrInstructionIdReturn:
case IrInstructionIdUnreachable:
case IrInstructionIdSetDebugSafety:
case IrInstructionIdSetCold:
case IrInstructionIdSetRuntimeSafety:
case IrInstructionIdSetFloatMode:
case IrInstructionIdImport:
case IrInstructionIdCompileErr:

View File

@ -368,11 +368,15 @@ static void ir_print_union_field_ptr(IrPrint *irp, IrInstructionUnionFieldPtr *i
fprintf(irp->f, ")");
}
static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {
fprintf(irp->f, "@setDebugSafety(");
ir_print_other_instruction(irp, instruction->scope_value);
fprintf(irp->f, ", ");
ir_print_other_instruction(irp, instruction->debug_safety_on);
static void ir_print_set_cold(IrPrint *irp, IrInstructionSetCold *instruction) {
fprintf(irp->f, "@setCold(");
ir_print_other_instruction(irp, instruction->is_cold);
fprintf(irp->f, ")");
}
static void ir_print_set_runtime_safety(IrPrint *irp, IrInstructionSetRuntimeSafety *instruction) {
fprintf(irp->f, "@setRuntimeSafety(");
ir_print_other_instruction(irp, instruction->safety_on);
fprintf(irp->f, ")");
}
@ -1081,8 +1085,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdUnionFieldPtr:
ir_print_union_field_ptr(irp, (IrInstructionUnionFieldPtr *)instruction);
break;
case IrInstructionIdSetDebugSafety:
ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);
case IrInstructionIdSetCold:
ir_print_set_cold(irp, (IrInstructionSetCold *)instruction);
break;
case IrInstructionIdSetRuntimeSafety:
ir_print_set_runtime_safety(irp, (IrInstructionSetRuntimeSafety *)instruction);
break;
case IrInstructionIdSetFloatMode:
ir_print_set_float_mode(irp, (IrInstructionSetFloatMode *)instruction);

View File

@ -462,7 +462,7 @@ int main(int argc, char **argv) {
Termination term;
os_spawn_process(buf_ptr(path_to_build_exe), args, &term);
if (term.how != TerminationIdClean || term.code != 0) {
fprintf(stderr, "\nBuild failed. Use the following command to reproduce the failure:\n");
fprintf(stderr, "\nBuild failed. The following command failed:\n");
fprintf(stderr, "%s", buf_ptr(path_to_build_exe));
for (size_t i = 0; i < args.length; i += 1) {
fprintf(stderr, " %s", args.at(i));

View File

@ -390,17 +390,15 @@ static int os_exec_process_posix(const char *exe, ZigList<const char *> &args,
#if defined(ZIG_OS_WINDOWS)
/*
static void win32_panic(const char *str) {
DWORD err = GetLastError();
LPSTR messageBuffer = nullptr;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
zig_panic(str, messageBuffer);
LocalFree(messageBuffer);
}
*/
//static void win32_panic(const char *str) {
// DWORD err = GetLastError();
// LPSTR messageBuffer = nullptr;
// FormatMessageA(
// FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
// NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
// zig_panic(str, messageBuffer);
// LocalFree(messageBuffer);
//}
static int os_exec_process_windows(const char *exe, ZigList<const char *> &args,
Termination *term, Buf *out_stderr, Buf *out_stdout)
@ -794,9 +792,18 @@ int os_delete_file(Buf *path) {
}
int os_rename(Buf *src_path, Buf *dest_path) {
if (buf_eql_buf(src_path, dest_path)) {
return 0;
}
#if defined(ZIG_OS_WINDOWS)
if (!MoveFileExA(buf_ptr(src_path), buf_ptr(dest_path), MOVEFILE_REPLACE_EXISTING)) {
return ErrorFileSystem;
}
#else
if (rename(buf_ptr(src_path), buf_ptr(dest_path)) == -1) {
return ErrorFileSystem;
}
#endif
return 0;
}

View File

@ -84,11 +84,6 @@ static AstNode *ast_create_node(ParseContext *pc, NodeType type, Token *first_to
return node;
}
static AstNode *ast_create_void_type_node(ParseContext *pc, Token *token) {
AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
node->data.symbol_expr.symbol = pc->void_buf;
return node;
}
static void parse_asm_template(ParseContext *pc, AstNode *node) {
Buf *asm_template = node->data.asm_expr.asm_template;
@ -1495,7 +1490,7 @@ static AstNode *ast_parse_break_expr(ParseContext *pc, size_t *token_index) {
}
/*
Defer(body) = option("%") "defer" body
Defer(body) = ("defer" | "errdefer") body
*/
static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
Token *token = &pc->tokens->at(*token_index);
@ -1503,15 +1498,10 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
NodeType node_type;
ReturnKind kind;
if (token->id == TokenIdPercent) {
Token *next_token = &pc->tokens->at(*token_index + 1);
if (next_token->id == TokenIdKeywordDefer) {
kind = ReturnKindError;
node_type = NodeTypeDefer;
*token_index += 2;
} else {
return nullptr;
}
if (token->id == TokenIdKeywordErrdefer) {
kind = ReturnKindError;
node_type = NodeTypeDefer;
*token_index += 1;
} else if (token->id == TokenIdKeywordDefer) {
kind = ReturnKindUnconditional;
node_type = NodeTypeDefer;
@ -2250,7 +2240,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
}
/*
FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)
FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") TypeExpr
*/
static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
Token *first_token = &pc->tokens->at(*token_index);
@ -2258,11 +2248,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
CallingConvention cc;
bool is_extern = false;
if (first_token->id == TokenIdKeywordColdCC) {
*token_index += 1;
fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
cc = CallingConventionCold;
} else if (first_token->id == TokenIdKeywordNakedCC) {
if (first_token->id == TokenIdKeywordNakedCC) {
*token_index += 1;
fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
cc = CallingConventionNaked;
@ -2329,12 +2315,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
ast_eat_token(pc, token_index, TokenIdRParen);
next_token = &pc->tokens->at(*token_index);
}
if (next_token->id == TokenIdArrow) {
*token_index += 1;
node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false);
} else {
node->data.fn_proto.return_type = ast_create_void_type_node(pc, next_token);
}
node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
return node;
}

View File

@ -112,13 +112,13 @@ static const struct ZigKeyword zig_keywords[] = {
{"asm", TokenIdKeywordAsm},
{"break", TokenIdKeywordBreak},
{"catch", TokenIdKeywordCatch},
{"coldcc", TokenIdKeywordColdCC},
{"comptime", TokenIdKeywordCompTime},
{"const", TokenIdKeywordConst},
{"continue", TokenIdKeywordContinue},
{"defer", TokenIdKeywordDefer},
{"else", TokenIdKeywordElse},
{"enum", TokenIdKeywordEnum},
{"errdefer", TokenIdKeywordErrdefer},
{"error", TokenIdKeywordError},
{"export", TokenIdKeywordExport},
{"extern", TokenIdKeywordExtern},
@ -1509,13 +1509,13 @@ const char * token_name(TokenId id) {
case TokenIdKeywordAsm: return "asm";
case TokenIdKeywordBreak: return "break";
case TokenIdKeywordCatch: return "catch";
case TokenIdKeywordColdCC: return "coldcc";
case TokenIdKeywordCompTime: return "comptime";
case TokenIdKeywordConst: return "const";
case TokenIdKeywordContinue: return "continue";
case TokenIdKeywordDefer: return "defer";
case TokenIdKeywordElse: return "else";
case TokenIdKeywordEnum: return "enum";
case TokenIdKeywordErrdefer: return "errdefer";
case TokenIdKeywordError: return "error";
case TokenIdKeywordExport: return "export";
case TokenIdKeywordExtern: return "extern";

View File

@ -51,13 +51,13 @@ enum TokenId {
TokenIdKeywordAsm,
TokenIdKeywordBreak,
TokenIdKeywordCatch,
TokenIdKeywordColdCC,
TokenIdKeywordCompTime,
TokenIdKeywordConst,
TokenIdKeywordContinue,
TokenIdKeywordDefer,
TokenIdKeywordElse,
TokenIdKeywordEnum,
TokenIdKeywordErrdefer,
TokenIdKeywordError,
TokenIdKeywordExport,
TokenIdKeywordExtern,

View File

@ -922,7 +922,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
// void foo(void) -> Foo;
// we want to keep the return type AST node.
if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
proto_node->data.fn_proto.return_type = nullptr;
proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "void");
}
}

View File

@ -4,11 +4,11 @@ const assert = debug.assert;
const mem = std.mem;
const Allocator = mem.Allocator;
pub fn ArrayList(comptime T: type) -> type {
pub fn ArrayList(comptime T: type) type {
return AlignedArrayList(T, @alignOf(T));
}
pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
return struct {
const Self = this;
@ -20,7 +20,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
allocator: &Allocator,
/// Deinitialize with `deinit` or use `toOwnedSlice`.
pub fn init(allocator: &Allocator) -> Self {
pub fn init(allocator: &Allocator) Self {
return Self {
.items = []align(A) T{},
.len = 0,
@ -28,22 +28,22 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
};
}
pub fn deinit(l: &Self) {
pub fn deinit(l: &Self) void {
l.allocator.free(l.items);
}
pub fn toSlice(l: &Self) -> []align(A) T {
pub fn toSlice(l: &Self) []align(A) T {
return l.items[0..l.len];
}
pub fn toSliceConst(l: &const Self) -> []align(A) const T {
pub fn toSliceConst(l: &const Self) []align(A) const T {
return l.items[0..l.len];
}
/// ArrayList takes ownership of the passed in slice. The slice must have been
/// allocated with `allocator`.
/// Deinitialize with `deinit` or use `toOwnedSlice`.
pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) -> Self {
pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) Self {
return Self {
.items = slice,
.len = slice.len,
@ -52,35 +52,35 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
}
/// The caller owns the returned memory. ArrayList becomes empty.
pub fn toOwnedSlice(self: &Self) -> []align(A) T {
pub fn toOwnedSlice(self: &Self) []align(A) T {
const allocator = self.allocator;
const result = allocator.alignedShrink(T, A, self.items, self.len);
*self = init(allocator);
return result;
}
pub fn append(l: &Self, item: &const T) -> %void {
pub fn append(l: &Self, item: &const T) %void {
const new_item_ptr = try l.addOne();
*new_item_ptr = *item;
}
pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void {
pub fn appendSlice(l: &Self, items: []align(A) const T) %void {
try l.ensureCapacity(l.len + items.len);
mem.copy(T, l.items[l.len..], items);
l.len += items.len;
}
pub fn resize(l: &Self, new_len: usize) -> %void {
pub fn resize(l: &Self, new_len: usize) %void {
try l.ensureCapacity(new_len);
l.len = new_len;
}
pub fn shrink(l: &Self, new_len: usize) {
pub fn shrink(l: &Self, new_len: usize) void {
assert(new_len <= l.len);
l.len = new_len;
}
pub fn ensureCapacity(l: &Self, new_capacity: usize) -> %void {
pub fn ensureCapacity(l: &Self, new_capacity: usize) %void {
var better_capacity = l.items.len;
if (better_capacity >= new_capacity) return;
while (true) {
@ -90,7 +90,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);
}
pub fn addOne(l: &Self) -> %&T {
pub fn addOne(l: &Self) %&T {
const new_length = l.len + 1;
try l.ensureCapacity(new_length);
const result = &l.items[l.len];
@ -98,12 +98,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
return result;
}
pub fn pop(self: &Self) -> T {
pub fn pop(self: &Self) T {
self.len -= 1;
return self.items[self.len];
}
pub fn popOrNull(self: &Self) -> ?T {
pub fn popOrNull(self: &Self) ?T {
if (self.len == 0)
return null;
return self.pop();

View File

@ -11,7 +11,7 @@ pub const Base64Encoder = struct {
pad_char: u8,
/// a bunch of assertions, then simply pass the data right through.
pub fn init(alphabet_chars: []const u8, pad_char: u8) -> Base64Encoder {
pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64Encoder {
assert(alphabet_chars.len == 64);
var char_in_alphabet = []bool{false} ** 256;
for (alphabet_chars) |c| {
@ -27,12 +27,12 @@ pub const Base64Encoder = struct {
}
/// ceil(source_len * 4/3)
pub fn calcSize(source_len: usize) -> usize {
pub fn calcSize(source_len: usize) usize {
return @divTrunc(source_len + 2, 3) * 4;
}
/// dest.len must be what you get from ::calcSize.
pub fn encode(encoder: &const Base64Encoder, dest: []u8, source: []const u8) {
pub fn encode(encoder: &const Base64Encoder, dest: []u8, source: []const u8) void {
assert(dest.len == Base64Encoder.calcSize(source.len));
var i: usize = 0;
@ -90,7 +90,7 @@ pub const Base64Decoder = struct {
char_in_alphabet: [256]bool,
pad_char: u8,
pub fn init(alphabet_chars: []const u8, pad_char: u8) -> Base64Decoder {
pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64Decoder {
assert(alphabet_chars.len == 64);
var result = Base64Decoder{
@ -111,7 +111,7 @@ pub const Base64Decoder = struct {
}
/// If the encoded buffer is detected to be invalid, returns error.InvalidPadding.
pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) -> %usize {
pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) %usize {
if (source.len % 4 != 0) return error.InvalidPadding;
return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
}
@ -119,7 +119,7 @@ pub const Base64Decoder = struct {
/// dest.len must be what you get from ::calcSize.
/// invalid characters result in error.InvalidCharacter.
/// invalid padding results in error.InvalidPadding.
pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) -> %void {
pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) %void {
assert(dest.len == (decoder.calcSize(source) catch unreachable));
assert(source.len % 4 == 0);
@ -168,7 +168,7 @@ error OutputTooSmall;
pub const Base64DecoderWithIgnore = struct {
decoder: Base64Decoder,
char_is_ignored: [256]bool,
pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) -> Base64DecoderWithIgnore {
pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) Base64DecoderWithIgnore {
var result = Base64DecoderWithIgnore {
.decoder = Base64Decoder.init(alphabet_chars, pad_char),
.char_is_ignored = []bool{false} ** 256,
@ -185,7 +185,7 @@ pub const Base64DecoderWithIgnore = struct {
}
/// If no characters end up being ignored or padding, this will be the exact decoded size.
pub fn calcSizeUpperBound(encoded_len: usize) -> %usize {
pub fn calcSizeUpperBound(encoded_len: usize) %usize {
return @divTrunc(encoded_len, 4) * 3;
}
@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct {
/// Invalid padding results in error.InvalidPadding.
/// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.
/// Returns the number of bytes writen to dest.
pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) -> %usize {
pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) %usize {
const decoder = &decoder_with_ignore.decoder;
var src_cursor: usize = 0;
@ -293,7 +293,7 @@ pub const Base64DecoderUnsafe = struct {
char_to_index: [256]u8,
pad_char: u8,
pub fn init(alphabet_chars: []const u8, pad_char: u8) -> Base64DecoderUnsafe {
pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64DecoderUnsafe {
assert(alphabet_chars.len == 64);
var result = Base64DecoderUnsafe {
.char_to_index = undefined,
@ -307,13 +307,13 @@ pub const Base64DecoderUnsafe = struct {
}
/// The source buffer must be valid.
pub fn calcSize(decoder: &const Base64DecoderUnsafe, source: []const u8) -> usize {
pub fn calcSize(decoder: &const Base64DecoderUnsafe, source: []const u8) usize {
return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
}
/// dest.len must be what you get from ::calcDecodedSizeExactUnsafe.
/// invalid characters or padding will result in undefined values.
pub fn decode(decoder: &const Base64DecoderUnsafe, dest: []u8, source: []const u8) {
pub fn decode(decoder: &const Base64DecoderUnsafe, dest: []u8, source: []const u8) void {
assert(dest.len == decoder.calcSize(source));
var src_index: usize = 0;
@ -359,7 +359,7 @@ pub const Base64DecoderUnsafe = struct {
}
};
fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) -> usize {
fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {
if (source.len == 0) return 0;
var result = @divExact(source.len, 4) * 3;
if (source[source.len - 1] == pad_char) {
@ -378,7 +378,7 @@ test "base64" {
comptime (testBase64() catch unreachable);
}
fn testBase64() -> %void {
fn testBase64() %void {
try testAllApis("", "");
try testAllApis("f", "Zg==");
try testAllApis("fo", "Zm8=");
@ -412,7 +412,7 @@ fn testBase64() -> %void {
try testOutputTooSmallError("AAAAAA==");
}
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void {
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void {
// Base64Encoder
{
var buffer: [0x100]u8 = undefined;
@ -449,7 +449,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v
}
}
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %void {
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %void {
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
@ -459,7 +459,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %
}
error ExpectedError;
fn testError(encoded: []const u8, expected_err: error) -> %void {
fn testError(encoded: []const u8, expected_err: error) %void {
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
@ -475,7 +475,7 @@ fn testError(encoded: []const u8, expected_err: error) -> %void {
} else |err| if (err != expected_err) return err;
}
fn testOutputTooSmallError(encoded: []const u8) -> %void {
fn testOutputTooSmallError(encoded: []const u8) %void {
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;

View File

@ -9,14 +9,14 @@ pub const BufMap = struct {
const BufMapHashMap = HashMap([]const u8, []const u8, mem.hash_slice_u8, mem.eql_slice_u8);
pub fn init(allocator: &Allocator) -> BufMap {
pub fn init(allocator: &Allocator) BufMap {
var self = BufMap {
.hash_map = BufMapHashMap.init(allocator),
};
return self;
}
pub fn deinit(self: &BufMap) {
pub fn deinit(self: &BufMap) void {
var it = self.hash_map.iterator();
while (true) {
const entry = it.next() ?? break;
@ -27,47 +27,47 @@ pub const BufMap = struct {
self.hash_map.deinit();
}
pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void {
pub fn set(self: &BufMap, key: []const u8, value: []const u8) %void {
if (self.hash_map.get(key)) |entry| {
const value_copy = try self.copy(value);
%defer self.free(value_copy);
errdefer self.free(value_copy);
_ = try self.hash_map.put(key, value_copy);
self.free(entry.value);
} else {
const key_copy = try self.copy(key);
%defer self.free(key_copy);
errdefer self.free(key_copy);
const value_copy = try self.copy(value);
%defer self.free(value_copy);
errdefer self.free(value_copy);
_ = try self.hash_map.put(key_copy, value_copy);
}
}
pub fn get(self: &BufMap, key: []const u8) -> ?[]const u8 {
pub fn get(self: &BufMap, key: []const u8) ?[]const u8 {
const entry = self.hash_map.get(key) ?? return null;
return entry.value;
}
pub fn delete(self: &BufMap, key: []const u8) {
pub fn delete(self: &BufMap, key: []const u8) void {
const entry = self.hash_map.remove(key) ?? return;
self.free(entry.key);
self.free(entry.value);
}
pub fn count(self: &const BufMap) -> usize {
pub fn count(self: &const BufMap) usize {
return self.hash_map.size;
}
pub fn iterator(self: &const BufMap) -> BufMapHashMap.Iterator {
pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {
return self.hash_map.iterator();
}
fn free(self: &BufMap, value: []const u8) {
fn free(self: &BufMap, value: []const u8) void {
// remove the const
const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
self.hash_map.allocator.free(mut_value);
}
fn copy(self: &BufMap, value: []const u8) -> %[]const u8 {
fn copy(self: &BufMap, value: []const u8) %[]const u8 {
const result = try self.hash_map.allocator.alloc(u8, value.len);
mem.copy(u8, result, value);
return result;

View File

@ -7,14 +7,14 @@ pub const BufSet = struct {
const BufSetHashMap = HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
pub fn init(a: &Allocator) -> BufSet {
pub fn init(a: &Allocator) BufSet {
var self = BufSet {
.hash_map = BufSetHashMap.init(a),
};
return self;
}
pub fn deinit(self: &BufSet) {
pub fn deinit(self: &BufSet) void {
var it = self.hash_map.iterator();
while (true) {
const entry = it.next() ?? break;
@ -24,38 +24,38 @@ pub const BufSet = struct {
self.hash_map.deinit();
}
pub fn put(self: &BufSet, key: []const u8) -> %void {
pub fn put(self: &BufSet, key: []const u8) %void {
if (self.hash_map.get(key) == null) {
const key_copy = try self.copy(key);
%defer self.free(key_copy);
errdefer self.free(key_copy);
_ = try self.hash_map.put(key_copy, {});
}
}
pub fn delete(self: &BufSet, key: []const u8) {
pub fn delete(self: &BufSet, key: []const u8) void {
const entry = self.hash_map.remove(key) ?? return;
self.free(entry.key);
}
pub fn count(self: &const BufSet) -> usize {
pub fn count(self: &const BufSet) usize {
return self.hash_map.size;
}
pub fn iterator(self: &const BufSet) -> BufSetHashMap.Iterator {
pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {
return self.hash_map.iterator();
}
pub fn allocator(self: &const BufSet) -> &Allocator {
pub fn allocator(self: &const BufSet) &Allocator {
return self.hash_map.allocator;
}
fn free(self: &BufSet, value: []const u8) {
fn free(self: &BufSet, value: []const u8) void {
// remove the const
const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
self.hash_map.allocator.free(mut_value);
}
fn copy(self: &BufSet, value: []const u8) -> %[]const u8 {
fn copy(self: &BufSet, value: []const u8) %[]const u8 {
const result = try self.hash_map.allocator.alloc(u8, value.len);
mem.copy(u8, result, value);
return result;

View File

@ -12,14 +12,14 @@ pub const Buffer = struct {
list: ArrayList(u8),
/// Must deinitialize with deinit.
pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer {
pub fn init(allocator: &Allocator, m: []const u8) %Buffer {
var self = try initSize(allocator, m.len);
mem.copy(u8, self.list.items, m);
return self;
}
/// Must deinitialize with deinit.
pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer {
pub fn initSize(allocator: &Allocator, size: usize) %Buffer {
var self = initNull(allocator);
try self.resize(size);
return self;
@ -30,21 +30,21 @@ pub const Buffer = struct {
/// * ::replaceContents
/// * ::replaceContentsBuffer
/// * ::resize
pub fn initNull(allocator: &Allocator) -> Buffer {
pub fn initNull(allocator: &Allocator) Buffer {
return Buffer {
.list = ArrayList(u8).init(allocator),
};
}
/// Must deinitialize with deinit.
pub fn initFromBuffer(buffer: &const Buffer) -> %Buffer {
pub fn initFromBuffer(buffer: &const Buffer) %Buffer {
return Buffer.init(buffer.list.allocator, buffer.toSliceConst());
}
/// Buffer takes ownership of the passed in slice. The slice must have been
/// allocated with `allocator`.
/// Must deinitialize with deinit.
pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) -> Buffer {
pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) Buffer {
var self = Buffer {
.list = ArrayList(u8).fromOwnedSlice(allocator, slice),
};
@ -54,7 +54,7 @@ pub const Buffer = struct {
/// The caller owns the returned memory. The Buffer becomes null and
/// is safe to `deinit`.
pub fn toOwnedSlice(self: &Buffer) -> []u8 {
pub fn toOwnedSlice(self: &Buffer) []u8 {
const allocator = self.list.allocator;
const result = allocator.shrink(u8, self.list.items, self.len());
*self = initNull(allocator);
@ -62,55 +62,55 @@ pub const Buffer = struct {
}
pub fn deinit(self: &Buffer) {
pub fn deinit(self: &Buffer) void {
self.list.deinit();
}
pub fn toSlice(self: &Buffer) -> []u8 {
pub fn toSlice(self: &Buffer) []u8 {
return self.list.toSlice()[0..self.len()];
}
pub fn toSliceConst(self: &const Buffer) -> []const u8 {
pub fn toSliceConst(self: &const Buffer) []const u8 {
return self.list.toSliceConst()[0..self.len()];
}
pub fn shrink(self: &Buffer, new_len: usize) {
pub fn shrink(self: &Buffer, new_len: usize) void {
assert(new_len <= self.len());
self.list.shrink(new_len + 1);
self.list.items[self.len()] = 0;
}
pub fn resize(self: &Buffer, new_len: usize) -> %void {
pub fn resize(self: &Buffer, new_len: usize) %void {
try self.list.resize(new_len + 1);
self.list.items[self.len()] = 0;
}
pub fn isNull(self: &const Buffer) -> bool {
pub fn isNull(self: &const Buffer) bool {
return self.list.len == 0;
}
pub fn len(self: &const Buffer) -> usize {
pub fn len(self: &const Buffer) usize {
return self.list.len - 1;
}
pub fn append(self: &Buffer, m: []const u8) -> %void {
pub fn append(self: &Buffer, m: []const u8) %void {
const old_len = self.len();
try self.resize(old_len + m.len);
mem.copy(u8, self.list.toSlice()[old_len..], m);
}
// TODO: remove, use OutStream for this
pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) -> %void {
pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) %void {
return fmt.format(self, append, format, args);
}
// TODO: remove, use OutStream for this
pub fn appendByte(self: &Buffer, byte: u8) -> %void {
pub fn appendByte(self: &Buffer, byte: u8) %void {
return self.appendByteNTimes(byte, 1);
}
// TODO: remove, use OutStream for this
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void {
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) %void {
var prev_size: usize = self.len();
const new_size = prev_size + count;
try self.resize(new_size);
@ -121,29 +121,29 @@ pub const Buffer = struct {
}
}
pub fn eql(self: &const Buffer, m: []const u8) -> bool {
pub fn eql(self: &const Buffer, m: []const u8) bool {
return mem.eql(u8, self.toSliceConst(), m);
}
pub fn startsWith(self: &const Buffer, m: []const u8) -> bool {
pub fn startsWith(self: &const Buffer, m: []const u8) bool {
if (self.len() < m.len) return false;
return mem.eql(u8, self.list.items[0..m.len], m);
}
pub fn endsWith(self: &const Buffer, m: []const u8) -> bool {
pub fn endsWith(self: &const Buffer, m: []const u8) bool {
const l = self.len();
if (l < m.len) return false;
const start = l - m.len;
return mem.eql(u8, self.list.items[start..l], m);
}
pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void {
pub fn replaceContents(self: &const Buffer, m: []const u8) %void {
try self.resize(m.len);
mem.copy(u8, self.list.toSlice(), m);
}
/// For passing to C functions.
pub fn ptr(self: &const Buffer) -> &u8 {
pub fn ptr(self: &const Buffer) &u8 {
return self.list.items.ptr;
}
};

View File

@ -90,7 +90,7 @@ pub const Builder = struct {
};
pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,
cache_root: []const u8) -> Builder
cache_root: []const u8) Builder
{
var self = Builder {
.zig_exe = zig_exe,
@ -136,7 +136,7 @@ pub const Builder = struct {
return self;
}
pub fn deinit(self: &Builder) {
pub fn deinit(self: &Builder) void {
self.lib_paths.deinit();
self.include_paths.deinit();
self.rpaths.deinit();
@ -144,85 +144,85 @@ pub const Builder = struct {
self.top_level_steps.deinit();
}
pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) {
pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) void {
self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default
self.lib_dir = os.path.join(self.allocator, self.prefix, "lib") catch unreachable;
self.exe_dir = os.path.join(self.allocator, self.prefix, "bin") catch unreachable;
}
pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {
pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
return LibExeObjStep.createExecutable(self, name, root_src);
}
pub fn addObject(self: &Builder, name: []const u8, root_src: []const u8) -> &LibExeObjStep {
pub fn addObject(self: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {
return LibExeObjStep.createObject(self, name, root_src);
}
pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8,
ver: &const Version) -> &LibExeObjStep
ver: &const Version) &LibExeObjStep
{
return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);
}
pub fn addStaticLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {
pub fn addStaticLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
return LibExeObjStep.createStaticLibrary(self, name, root_src);
}
pub fn addTest(self: &Builder, root_src: []const u8) -> &TestStep {
pub fn addTest(self: &Builder, root_src: []const u8) &TestStep {
const test_step = self.allocator.create(TestStep) catch unreachable;
*test_step = TestStep.init(self, root_src);
return test_step;
}
pub fn addAssemble(self: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep {
pub fn addAssemble(self: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
const obj_step = LibExeObjStep.createObject(self, name, null);
obj_step.addAssemblyFile(src);
return obj_step;
}
pub fn addCStaticLibrary(self: &Builder, name: []const u8) -> &LibExeObjStep {
pub fn addCStaticLibrary(self: &Builder, name: []const u8) &LibExeObjStep {
return LibExeObjStep.createCStaticLibrary(self, name);
}
pub fn addCSharedLibrary(self: &Builder, name: []const u8, ver: &const Version) -> &LibExeObjStep {
pub fn addCSharedLibrary(self: &Builder, name: []const u8, ver: &const Version) &LibExeObjStep {
return LibExeObjStep.createCSharedLibrary(self, name, ver);
}
pub fn addCExecutable(self: &Builder, name: []const u8) -> &LibExeObjStep {
pub fn addCExecutable(self: &Builder, name: []const u8) &LibExeObjStep {
return LibExeObjStep.createCExecutable(self, name);
}
pub fn addCObject(self: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep {
pub fn addCObject(self: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
return LibExeObjStep.createCObject(self, name, src);
}
/// ::argv is copied.
pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
argv: []const []const u8) -> &CommandStep
argv: []const []const u8) &CommandStep
{
return CommandStep.create(self, cwd, env_map, argv);
}
pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) -> &WriteFileStep {
pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) &WriteFileStep {
const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
*write_file_step = WriteFileStep.init(self, file_path, data);
return write_file_step;
}
pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) -> &LogStep {
pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) &LogStep {
const data = self.fmt(format, args);
const log_step = self.allocator.create(LogStep) catch unreachable;
*log_step = LogStep.init(self, data);
return log_step;
}
pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) -> &RemoveDirStep {
pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) &RemoveDirStep {
const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
*remove_dir_step = RemoveDirStep.init(self, dir_path);
return remove_dir_step;
}
pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) -> Version {
pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) Version {
return Version {
.major = major,
.minor = minor,
@ -230,19 +230,19 @@ pub const Builder = struct {
};
}
pub fn addCIncludePath(self: &Builder, path: []const u8) {
pub fn addCIncludePath(self: &Builder, path: []const u8) void {
self.include_paths.append(path) catch unreachable;
}
pub fn addRPath(self: &Builder, path: []const u8) {
pub fn addRPath(self: &Builder, path: []const u8) void {
self.rpaths.append(path) catch unreachable;
}
pub fn addLibPath(self: &Builder, path: []const u8) {
pub fn addLibPath(self: &Builder, path: []const u8) void {
self.lib_paths.append(path) catch unreachable;
}
pub fn make(self: &Builder, step_names: []const []const u8) -> %void {
pub fn make(self: &Builder, step_names: []const []const u8) %void {
var wanted_steps = ArrayList(&Step).init(self.allocator);
defer wanted_steps.deinit();
@ -260,7 +260,7 @@ pub const Builder = struct {
}
}
pub fn getInstallStep(self: &Builder) -> &Step {
pub fn getInstallStep(self: &Builder) &Step {
if (self.have_install_step)
return &self.install_tls.step;
@ -269,7 +269,7 @@ pub const Builder = struct {
return &self.install_tls.step;
}
pub fn getUninstallStep(self: &Builder) -> &Step {
pub fn getUninstallStep(self: &Builder) &Step {
if (self.have_uninstall_step)
return &self.uninstall_tls.step;
@ -278,7 +278,7 @@ pub const Builder = struct {
return &self.uninstall_tls.step;
}
fn makeUninstall(uninstall_step: &Step) -> %void {
fn makeUninstall(uninstall_step: &Step) %void {
const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
@ -292,7 +292,7 @@ pub const Builder = struct {
// TODO remove empty directories
}
fn makeOneStep(self: &Builder, s: &Step) -> %void {
fn makeOneStep(self: &Builder, s: &Step) %void {
if (s.loop_flag) {
warn("Dependency loop detected:\n {}\n", s.name);
return error.DependencyLoopDetected;
@ -313,7 +313,7 @@ pub const Builder = struct {
try s.make();
}
fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step {
fn getTopLevelStepByName(self: &Builder, name: []const u8) %&Step {
for (self.top_level_steps.toSliceConst()) |top_level_step| {
if (mem.eql(u8, top_level_step.step.name, name)) {
return &top_level_step.step;
@ -323,7 +323,7 @@ pub const Builder = struct {
return error.InvalidStepName;
}
fn processNixOSEnvVars(self: &Builder) {
fn processNixOSEnvVars(self: &Builder) void {
if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
var it = mem.split(nix_cflags_compile, " ");
while (true) {
@ -365,7 +365,7 @@ pub const Builder = struct {
}
}
pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) -> ?T {
pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
const type_id = comptime typeToEnum(T);
const available_option = AvailableOption {
.name = name,
@ -418,7 +418,7 @@ pub const Builder = struct {
}
}
pub fn step(self: &Builder, name: []const u8, description: []const u8) -> &Step {
pub fn step(self: &Builder, name: []const u8, description: []const u8) &Step {
const step_info = self.allocator.create(TopLevelStep) catch unreachable;
*step_info = TopLevelStep {
.step = Step.initNoOp(name, self.allocator),
@ -428,7 +428,7 @@ pub const Builder = struct {
return &step_info.step;
}
pub fn standardReleaseOptions(self: &Builder) -> builtin.Mode {
pub fn standardReleaseOptions(self: &Builder) builtin.Mode {
if (self.release_mode) |mode| return mode;
const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false;
@ -449,7 +449,7 @@ pub const Builder = struct {
return mode;
}
pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool {
pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) bool {
if (self.user_input_options.put(name, UserInputOption {
.name = name,
.value = UserValue { .Scalar = value },
@ -486,7 +486,7 @@ pub const Builder = struct {
return false;
}
pub fn addUserInputFlag(self: &Builder, name: []const u8) -> bool {
pub fn addUserInputFlag(self: &Builder, name: []const u8) bool {
if (self.user_input_options.put(name, UserInputOption {
.name = name,
.value = UserValue {.Flag = {} },
@ -507,7 +507,7 @@ pub const Builder = struct {
return false;
}
fn typeToEnum(comptime T: type) -> TypeId {
fn typeToEnum(comptime T: type) TypeId {
return switch (@typeId(T)) {
builtin.TypeId.Int => TypeId.Int,
builtin.TypeId.Float => TypeId.Float,
@ -520,11 +520,11 @@ pub const Builder = struct {
};
}
fn markInvalidUserInput(self: &Builder) {
fn markInvalidUserInput(self: &Builder) void {
self.invalid_user_input = true;
}
pub fn typeIdName(id: TypeId) -> []const u8 {
pub fn typeIdName(id: TypeId) []const u8 {
return switch (id) {
TypeId.Bool => "bool",
TypeId.Int => "int",
@ -534,7 +534,7 @@ pub const Builder = struct {
};
}
pub fn validateUserInputDidItFail(self: &Builder) -> bool {
pub fn validateUserInputDidItFail(self: &Builder) bool {
// make sure all args are used
var it = self.user_input_options.iterator();
while (true) {
@ -548,11 +548,11 @@ pub const Builder = struct {
return self.invalid_user_input;
}
fn spawnChild(self: &Builder, argv: []const []const u8) -> %void {
fn spawnChild(self: &Builder, argv: []const []const u8) %void {
return self.spawnChildEnvMap(null, &self.env_map, argv);
}
fn printCmd(cwd: ?[]const u8, argv: []const []const u8) {
fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
if (cwd) |yes_cwd| warn("cd {} && ", yes_cwd);
for (argv) |arg| {
warn("{} ", arg);
@ -561,7 +561,7 @@ pub const Builder = struct {
}
fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
argv: []const []const u8) -> %void
argv: []const []const u8) %void
{
if (self.verbose) {
printCmd(cwd, argv);
@ -595,28 +595,28 @@ pub const Builder = struct {
}
}
pub fn makePath(self: &Builder, path: []const u8) -> %void {
pub fn makePath(self: &Builder, path: []const u8) %void {
os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
warn("Unable to create path {}: {}\n", path, @errorName(err));
return err;
};
}
pub fn installArtifact(self: &Builder, artifact: &LibExeObjStep) {
pub fn installArtifact(self: &Builder, artifact: &LibExeObjStep) void {
self.getInstallStep().dependOn(&self.addInstallArtifact(artifact).step);
}
pub fn addInstallArtifact(self: &Builder, artifact: &LibExeObjStep) -> &InstallArtifactStep {
pub fn addInstallArtifact(self: &Builder, artifact: &LibExeObjStep) &InstallArtifactStep {
return InstallArtifactStep.create(self, artifact);
}
///::dest_rel_path is relative to prefix path or it can be an absolute path
pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) {
pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) void {
self.getInstallStep().dependOn(&self.addInstallFile(src_path, dest_rel_path).step);
}
///::dest_rel_path is relative to prefix path or it can be an absolute path
pub fn addInstallFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) -> &InstallFileStep {
pub fn addInstallFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) &InstallFileStep {
const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
self.pushInstalledFile(full_dest_path);
@ -625,16 +625,16 @@ pub const Builder = struct {
return install_step;
}
pub fn pushInstalledFile(self: &Builder, full_path: []const u8) {
pub fn pushInstalledFile(self: &Builder, full_path: []const u8) void {
_ = self.getUninstallStep();
self.installed_files.append(full_path) catch unreachable;
}
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) -> %void {
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) %void {
return self.copyFileMode(source_path, dest_path, 0o666);
}
fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void {
fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) %void {
if (self.verbose) {
warn("cp {} {}\n", source_path, dest_path);
}
@ -651,15 +651,15 @@ pub const Builder = struct {
};
}
fn pathFromRoot(self: &Builder, rel_path: []const u8) -> []u8 {
fn pathFromRoot(self: &Builder, rel_path: []const u8) []u8 {
return os.path.resolve(self.allocator, self.build_root, rel_path) catch unreachable;
}
pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 {
pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) []u8 {
return fmt_lib.allocPrint(self.allocator, format, args) catch unreachable;
}
fn getCCExe(self: &Builder) -> []const u8 {
fn getCCExe(self: &Builder) []const u8 {
if (builtin.environ == builtin.Environ.msvc) {
return "cl.exe";
} else {
@ -672,7 +672,7 @@ pub const Builder = struct {
}
}
pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) -> %[]const u8 {
pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) %[]const u8 {
// TODO report error for ambiguous situations
const exe_extension = (Target { .Native = {}}).exeFileExt();
for (self.search_prefixes.toSliceConst()) |search_prefix| {
@ -721,7 +721,7 @@ pub const Builder = struct {
return error.FileNotFound;
}
pub fn exec(self: &Builder, argv: []const []const u8) -> %[]u8 {
pub fn exec(self: &Builder, argv: []const []const u8) %[]u8 {
const max_output_size = 100 * 1024;
const result = try os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size);
switch (result.term) {
@ -743,7 +743,7 @@ pub const Builder = struct {
}
}
pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) {
pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) void {
self.search_prefixes.append(search_prefix) catch unreachable;
}
};
@ -764,7 +764,7 @@ pub const Target = union(enum) {
Native: void,
Cross: CrossTarget,
pub fn oFileExt(self: &const Target) -> []const u8 {
pub fn oFileExt(self: &const Target) []const u8 {
const environ = switch (*self) {
Target.Native => builtin.environ,
Target.Cross => |t| t.environ,
@ -775,42 +775,42 @@ pub const Target = union(enum) {
};
}
pub fn exeFileExt(self: &const Target) -> []const u8 {
pub fn exeFileExt(self: &const Target) []const u8 {
return switch (self.getOs()) {
builtin.Os.windows => ".exe",
else => "",
};
}
pub fn libFileExt(self: &const Target) -> []const u8 {
pub fn libFileExt(self: &const Target) []const u8 {
return switch (self.getOs()) {
builtin.Os.windows => ".lib",
else => ".a",
};
}
pub fn getOs(self: &const Target) -> builtin.Os {
pub fn getOs(self: &const Target) builtin.Os {
return switch (*self) {
Target.Native => builtin.os,
Target.Cross => |t| t.os,
};
}
pub fn isDarwin(self: &const Target) -> bool {
pub fn isDarwin(self: &const Target) bool {
return switch (self.getOs()) {
builtin.Os.ios, builtin.Os.macosx => true,
else => false,
};
}
pub fn isWindows(self: &const Target) -> bool {
pub fn isWindows(self: &const Target) bool {
return switch (self.getOs()) {
builtin.Os.windows => true,
else => false,
};
}
pub fn wantSharedLibSymLinks(self: &const Target) -> bool {
pub fn wantSharedLibSymLinks(self: &const Target) bool {
return !self.isWindows();
}
};
@ -865,58 +865,58 @@ pub const LibExeObjStep = struct {
};
pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8,
ver: &const Version) -> &LibExeObjStep
ver: &const Version) &LibExeObjStep
{
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
return self;
}
pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) -> &LibExeObjStep {
pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initC(builder, name, Kind.Lib, version, false);
return self;
}
pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {
pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
return self;
}
pub fn createCStaticLibrary(builder: &Builder, name: []const u8) -> &LibExeObjStep {
pub fn createCStaticLibrary(builder: &Builder, name: []const u8) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
return self;
}
pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) -> &LibExeObjStep {
pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
return self;
}
pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep {
pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
self.object_src = src;
return self;
}
pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {
pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));
return self;
}
pub fn createCExecutable(builder: &Builder, name: []const u8) -> &LibExeObjStep {
pub fn createCExecutable(builder: &Builder, name: []const u8) &LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
*self = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
return self;
}
fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind,
static: bool, ver: &const Version) -> LibExeObjStep
static: bool, ver: &const Version) LibExeObjStep
{
var self = LibExeObjStep {
.strip = false,
@ -956,7 +956,7 @@ pub const LibExeObjStep = struct {
return self;
}
fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) -> LibExeObjStep {
fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) LibExeObjStep {
var self = LibExeObjStep {
.builder = builder,
.name = name,
@ -996,7 +996,7 @@ pub const LibExeObjStep = struct {
return self;
}
fn computeOutFileNames(self: &LibExeObjStep) {
fn computeOutFileNames(self: &LibExeObjStep) void {
switch (self.kind) {
Kind.Obj => {
self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt());
@ -1031,7 +1031,7 @@ pub const LibExeObjStep = struct {
}
pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,
target_environ: builtin.Environ)
target_environ: builtin.Environ) void
{
self.target = Target {
.Cross = CrossTarget {
@ -1044,16 +1044,16 @@ pub const LibExeObjStep = struct {
}
// TODO respect this in the C args
pub fn setLinkerScriptPath(self: &LibExeObjStep, path: []const u8) {
pub fn setLinkerScriptPath(self: &LibExeObjStep, path: []const u8) void {
self.linker_script = path;
}
pub fn linkFramework(self: &LibExeObjStep, framework_name: []const u8) {
pub fn linkFramework(self: &LibExeObjStep, framework_name: []const u8) void {
assert(self.target.isDarwin());
self.frameworks.put(framework_name) catch unreachable;
}
pub fn linkLibrary(self: &LibExeObjStep, lib: &LibExeObjStep) {
pub fn linkLibrary(self: &LibExeObjStep, lib: &LibExeObjStep) void {
assert(self.kind != Kind.Obj);
assert(lib.kind == Kind.Lib);
@ -1074,26 +1074,26 @@ pub const LibExeObjStep = struct {
}
}
pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) {
pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) void {
assert(self.kind != Kind.Obj);
self.link_libs.put(name) catch unreachable;
}
pub fn addSourceFile(self: &LibExeObjStep, file: []const u8) {
pub fn addSourceFile(self: &LibExeObjStep, file: []const u8) void {
assert(self.kind != Kind.Obj);
assert(!self.is_zig);
self.source_files.append(file) catch unreachable;
}
pub fn setVerboseLink(self: &LibExeObjStep, value: bool) {
pub fn setVerboseLink(self: &LibExeObjStep, value: bool) void {
self.verbose_link = value;
}
pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) {
pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) void {
self.build_mode = mode;
}
pub fn setOutputPath(self: &LibExeObjStep, file_path: []const u8) {
pub fn setOutputPath(self: &LibExeObjStep, file_path: []const u8) void {
self.output_path = file_path;
// catch a common mistake
@ -1102,14 +1102,14 @@ pub const LibExeObjStep = struct {
}
}
pub fn getOutputPath(self: &LibExeObjStep) -> []const u8 {
pub fn getOutputPath(self: &LibExeObjStep) []const u8 {
return if (self.output_path) |output_path|
output_path
else
os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename) catch unreachable;
}
pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) {
pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) void {
self.output_h_path = file_path;
// catch a common mistake
@ -1118,24 +1118,24 @@ pub const LibExeObjStep = struct {
}
}
pub fn getOutputHPath(self: &LibExeObjStep) -> []const u8 {
pub fn getOutputHPath(self: &LibExeObjStep) []const u8 {
return if (self.output_h_path) |output_h_path|
output_h_path
else
os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) catch unreachable;
}
pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) {
pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) void {
self.assembly_files.append(path) catch unreachable;
}
pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) {
pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) void {
assert(self.kind != Kind.Obj);
self.object_files.append(path) catch unreachable;
}
pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) {
pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) void {
assert(obj.kind == Kind.Obj);
assert(self.kind != Kind.Obj);
@ -1152,15 +1152,15 @@ pub const LibExeObjStep = struct {
self.include_dirs.append(self.builder.cache_root) catch unreachable;
}
pub fn addIncludeDir(self: &LibExeObjStep, path: []const u8) {
pub fn addIncludeDir(self: &LibExeObjStep, path: []const u8) void {
self.include_dirs.append(path) catch unreachable;
}
pub fn addLibPath(self: &LibExeObjStep, path: []const u8) {
pub fn addLibPath(self: &LibExeObjStep, path: []const u8) void {
self.lib_paths.append(path) catch unreachable;
}
pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) {
pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void {
assert(self.is_zig);
self.packages.append(Pkg {
@ -1169,23 +1169,23 @@ pub const LibExeObjStep = struct {
}) catch unreachable;
}
pub fn addCompileFlags(self: &LibExeObjStep, flags: []const []const u8) {
pub fn addCompileFlags(self: &LibExeObjStep, flags: []const []const u8) void {
for (flags) |flag| {
self.cflags.append(flag) catch unreachable;
}
}
pub fn setNoStdLib(self: &LibExeObjStep, disable: bool) {
pub fn setNoStdLib(self: &LibExeObjStep, disable: bool) void {
assert(!self.is_zig);
self.disable_libc = disable;
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(LibExeObjStep, "step", step);
return if (self.is_zig) self.makeZig() else self.makeC();
}
fn makeZig(self: &LibExeObjStep) -> %void {
fn makeZig(self: &LibExeObjStep) %void {
const builder = self.builder;
assert(self.is_zig);
@ -1351,7 +1351,7 @@ pub const LibExeObjStep = struct {
}
}
fn appendCompileFlags(self: &LibExeObjStep, args: &ArrayList([]const u8)) {
fn appendCompileFlags(self: &LibExeObjStep, args: &ArrayList([]const u8)) void {
if (!self.strip) {
args.append("-g") catch unreachable;
}
@ -1396,7 +1396,7 @@ pub const LibExeObjStep = struct {
}
}
fn makeC(self: &LibExeObjStep) -> %void {
fn makeC(self: &LibExeObjStep) %void {
const builder = self.builder;
const cc = builder.getCCExe();
@ -1635,7 +1635,7 @@ pub const TestStep = struct {
target: Target,
exec_cmd_args: ?[]const ?[]const u8,
pub fn init(builder: &Builder, root_src: []const u8) -> TestStep {
pub fn init(builder: &Builder, root_src: []const u8) TestStep {
const step_name = builder.fmt("test {}", root_src);
return TestStep {
.step = Step.init(step_name, builder.allocator, make),
@ -1651,28 +1651,28 @@ pub const TestStep = struct {
};
}
pub fn setVerbose(self: &TestStep, value: bool) {
pub fn setVerbose(self: &TestStep, value: bool) void {
self.verbose = value;
}
pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) {
pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) void {
self.build_mode = mode;
}
pub fn linkSystemLibrary(self: &TestStep, name: []const u8) {
pub fn linkSystemLibrary(self: &TestStep, name: []const u8) void {
self.link_libs.put(name) catch unreachable;
}
pub fn setNamePrefix(self: &TestStep, text: []const u8) {
pub fn setNamePrefix(self: &TestStep, text: []const u8) void {
self.name_prefix = text;
}
pub fn setFilter(self: &TestStep, text: ?[]const u8) {
pub fn setFilter(self: &TestStep, text: ?[]const u8) void {
self.filter = text;
}
pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,
target_environ: builtin.Environ)
target_environ: builtin.Environ) void
{
self.target = Target {
.Cross = CrossTarget {
@ -1683,11 +1683,11 @@ pub const TestStep = struct {
};
}
pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) {
pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) void {
self.exec_cmd_args = args;
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(TestStep, "step", step);
const builder = self.builder;
@ -1781,7 +1781,7 @@ pub const CommandStep = struct {
/// ::argv is copied.
pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
argv: []const []const u8) -> &CommandStep
argv: []const []const u8) &CommandStep
{
const self = builder.allocator.create(CommandStep) catch unreachable;
*self = CommandStep {
@ -1796,7 +1796,7 @@ pub const CommandStep = struct {
return self;
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(CommandStep, "step", step);
const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;
@ -1812,7 +1812,7 @@ const InstallArtifactStep = struct {
const Self = this;
pub fn create(builder: &Builder, artifact: &LibExeObjStep) -> &Self {
pub fn create(builder: &Builder, artifact: &LibExeObjStep) &Self {
const self = builder.allocator.create(Self) catch unreachable;
const dest_dir = switch (artifact.kind) {
LibExeObjStep.Kind.Obj => unreachable,
@ -1836,7 +1836,7 @@ const InstallArtifactStep = struct {
return self;
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(Self, "step", step);
const builder = self.builder;
@ -1859,7 +1859,7 @@ pub const InstallFileStep = struct {
src_path: []const u8,
dest_path: []const u8,
pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) -> InstallFileStep {
pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) InstallFileStep {
return InstallFileStep {
.builder = builder,
.step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
@ -1868,7 +1868,7 @@ pub const InstallFileStep = struct {
};
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(InstallFileStep, "step", step);
try self.builder.copyFile(self.src_path, self.dest_path);
}
@ -1880,7 +1880,7 @@ pub const WriteFileStep = struct {
file_path: []const u8,
data: []const u8,
pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) -> WriteFileStep {
pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) WriteFileStep {
return WriteFileStep {
.builder = builder,
.step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
@ -1889,7 +1889,7 @@ pub const WriteFileStep = struct {
};
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(WriteFileStep, "step", step);
const full_path = self.builder.pathFromRoot(self.file_path);
const full_path_dir = os.path.dirname(full_path);
@ -1909,7 +1909,7 @@ pub const LogStep = struct {
builder: &Builder,
data: []const u8,
pub fn init(builder: &Builder, data: []const u8) -> LogStep {
pub fn init(builder: &Builder, data: []const u8) LogStep {
return LogStep {
.builder = builder,
.step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
@ -1917,7 +1917,7 @@ pub const LogStep = struct {
};
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(LogStep, "step", step);
warn("{}", self.data);
}
@ -1928,7 +1928,7 @@ pub const RemoveDirStep = struct {
builder: &Builder,
dir_path: []const u8,
pub fn init(builder: &Builder, dir_path: []const u8) -> RemoveDirStep {
pub fn init(builder: &Builder, dir_path: []const u8) RemoveDirStep {
return RemoveDirStep {
.builder = builder,
.step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),
@ -1936,7 +1936,7 @@ pub const RemoveDirStep = struct {
};
}
fn make(step: &Step) -> %void {
fn make(step: &Step) %void {
const self = @fieldParentPtr(RemoveDirStep, "step", step);
const full_path = self.builder.pathFromRoot(self.dir_path);
@ -1949,12 +1949,12 @@ pub const RemoveDirStep = struct {
pub const Step = struct {
name: []const u8,
makeFn: fn(self: &Step) -> %void,
makeFn: fn(self: &Step) %void,
dependencies: ArrayList(&Step),
loop_flag: bool,
done_flag: bool,
pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)->%void) -> Step {
pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)%void) Step {
return Step {
.name = name,
.makeFn = makeFn,
@ -1963,11 +1963,11 @@ pub const Step = struct {
.done_flag = false,
};
}
pub fn initNoOp(name: []const u8, allocator: &Allocator) -> Step {
pub fn initNoOp(name: []const u8, allocator: &Allocator) Step {
return init(name, allocator, makeNoOp);
}
pub fn make(self: &Step) -> %void {
pub fn make(self: &Step) %void {
if (self.done_flag)
return;
@ -1975,15 +1975,15 @@ pub const Step = struct {
self.done_flag = true;
}
pub fn dependOn(self: &Step, other: &Step) {
pub fn dependOn(self: &Step, other: &Step) void {
self.dependencies.append(other) catch unreachable;
}
fn makeNoOp(self: &Step) -> %void {}
fn makeNoOp(self: &Step) %void {}
};
fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,
filename_name_only: []const u8) -> %void
filename_name_only: []const u8) %void
{
const out_dir = os.path.dirname(output_path);
const out_basename = os.path.basename(output_path);

View File

@ -1,5 +1,5 @@
extern "c" fn __error() -> &c_int;
pub extern "c" fn _NSGetExecutablePath(buf: &u8, bufsize: &u32) -> c_int;
extern "c" fn __error() &c_int;
pub extern "c" fn _NSGetExecutablePath(buf: &u8, bufsize: &u32) c_int;
pub use @import("../os/darwin_errno.zig");
@ -41,7 +41,7 @@ pub const sigset_t = u32;
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
pub const Sigaction = extern struct {
handler: extern fn(c_int),
handler: extern fn(c_int)void,
sa_mask: sigset_t,
sa_flags: c_int,
};

View File

@ -9,43 +9,43 @@ pub use switch(builtin.os) {
};
const empty_import = @import("../empty.zig");
pub extern "c" fn abort() -> noreturn;
pub extern "c" fn exit(code: c_int) -> noreturn;
pub extern "c" fn isatty(fd: c_int) -> c_int;
pub extern "c" fn close(fd: c_int) -> c_int;
pub extern "c" fn fstat(fd: c_int, buf: &Stat) -> c_int;
pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: &Stat) -> c_int;
pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) -> isize;
pub extern "c" fn open(path: &const u8, oflag: c_int, ...) -> c_int;
pub extern "c" fn raise(sig: c_int) -> c_int;
pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) -> isize;
pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) -> c_int;
pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) -> c_int;
pub extern "c" fn abort() noreturn;
pub extern "c" fn exit(code: c_int) noreturn;
pub extern "c" fn isatty(fd: c_int) c_int;
pub extern "c" fn close(fd: c_int) c_int;
pub extern "c" fn fstat(fd: c_int, buf: &Stat) c_int;
pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: &Stat) c_int;
pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) isize;
pub extern "c" fn open(path: &const u8, oflag: c_int, ...) c_int;
pub extern "c" fn raise(sig: c_int) c_int;
pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) isize;
pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) c_int;
pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) c_int;
pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,
fd: c_int, offset: isize) -> ?&c_void;
pub extern "c" fn munmap(addr: &c_void, len: usize) -> c_int;
pub extern "c" fn unlink(path: &const u8) -> c_int;
pub extern "c" fn getcwd(buf: &u8, size: usize) -> ?&u8;
pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) -> c_int;
pub extern "c" fn fork() -> c_int;
pub extern "c" fn pipe(fds: &c_int) -> c_int;
pub extern "c" fn mkdir(path: &const u8, mode: c_uint) -> c_int;
pub extern "c" fn symlink(existing: &const u8, new: &const u8) -> c_int;
pub extern "c" fn rename(old: &const u8, new: &const u8) -> c_int;
pub extern "c" fn chdir(path: &const u8) -> c_int;
fd: c_int, offset: isize) ?&c_void;
pub extern "c" fn munmap(addr: &c_void, len: usize) c_int;
pub extern "c" fn unlink(path: &const u8) c_int;
pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8;
pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) c_int;
pub extern "c" fn fork() c_int;
pub extern "c" fn pipe(fds: &c_int) c_int;
pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int;
pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int;
pub extern "c" fn rename(old: &const u8, new: &const u8) c_int;
pub extern "c" fn chdir(path: &const u8) c_int;
pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,
envp: &const ?&const u8) -> c_int;
pub extern "c" fn dup(fd: c_int) -> c_int;
pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) -> c_int;
pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) -> isize;
pub extern "c" fn realpath(noalias file_name: &const u8, noalias resolved_name: &u8) -> ?&u8;
pub extern "c" fn sigprocmask(how: c_int, noalias set: &const sigset_t, noalias oset: ?&sigset_t) -> c_int;
pub extern "c" fn sigaction(sig: c_int, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> c_int;
pub extern "c" fn nanosleep(rqtp: &const timespec, rmtp: ?&timespec) -> c_int;
pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) -> c_int;
pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) -> c_int;
envp: &const ?&const u8) c_int;
pub extern "c" fn dup(fd: c_int) c_int;
pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;
pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) isize;
pub extern "c" fn realpath(noalias file_name: &const u8, noalias resolved_name: &u8) ?&u8;
pub extern "c" fn sigprocmask(how: c_int, noalias set: &const sigset_t, noalias oset: ?&sigset_t) c_int;
pub extern "c" fn sigaction(sig: c_int, noalias act: &const Sigaction, noalias oact: ?&Sigaction) c_int;
pub extern "c" fn nanosleep(rqtp: &const timespec, rmtp: ?&timespec) c_int;
pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;
pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;
pub extern "c" fn malloc(usize) -> ?&c_void;
pub extern "c" fn realloc(&c_void, usize) -> ?&c_void;
pub extern "c" fn free(&c_void);
pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) -> c_int;
pub extern "c" fn malloc(usize) ?&c_void;
pub extern "c" fn realloc(&c_void, usize) ?&c_void;
pub extern "c" fn free(&c_void) void;
pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) c_int;

View File

@ -1,5 +1,5 @@
pub use @import("../os/linux_errno.zig");
pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize, flags: c_uint) -> c_int;
extern "c" fn __errno_location() -> &c_int;
pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize, flags: c_uint) c_int;
extern "c" fn __errno_location() &c_int;
pub const _errno = __errno_location;

View File

@ -1 +1 @@
pub extern "c" fn _errno() -> &c_int;
pub extern "c" fn _errno() &c_int;

View File

@ -9,7 +9,7 @@ const RoundParam = struct {
a: usize, b: usize, c: usize, d: usize, x: usize, y: usize,
};
fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) -> RoundParam {
fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {
return RoundParam { .a = a, .b = b, .c = c, .d = d, .x = x, .y = y, };
}
@ -19,7 +19,7 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) -> RoundParam
pub const Blake2s224 = Blake2s(224);
pub const Blake2s256 = Blake2s(256);
fn Blake2s(comptime out_len: usize) -> type { return struct {
fn Blake2s(comptime out_len: usize) type { return struct {
const Self = this;
const block_size = 64;
const digest_size = out_len / 8;
@ -48,7 +48,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
buf: [64]u8,
buf_len: u8,
pub fn init() -> Self {
pub fn init() Self {
debug.assert(8 <= out_len and out_len <= 512);
var s: Self = undefined;
@ -56,7 +56,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
return s;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
mem.copy(u32, d.h[0..], iv[0..]);
// No key plus default parameters
@ -65,13 +65,13 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
d.buf_len = 0;
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Self.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var off: usize = 0;
// Partial buffer exists from previous update. Copy into buffer then hash.
@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
d.buf_len += u8(b[off..].len);
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
debug.assert(out.len >= out_len / 8);
mem.set(u8, d.buf[d.buf_len..], 0);
@ -108,7 +108,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
}
}
fn round(d: &Self, b: []const u8, last: bool) {
fn round(d: &Self, b: []const u8, last: bool) void {
debug.assert(b.len == 64);
var m: [16]u32 = undefined;
@ -236,7 +236,7 @@ test "blake2s256 streaming" {
pub const Blake2b384 = Blake2b(384);
pub const Blake2b512 = Blake2b(512);
fn Blake2b(comptime out_len: usize) -> type { return struct {
fn Blake2b(comptime out_len: usize) type { return struct {
const Self = this;
const block_size = 128;
const digest_size = out_len / 8;
@ -269,7 +269,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
buf: [128]u8,
buf_len: u8,
pub fn init() -> Self {
pub fn init() Self {
debug.assert(8 <= out_len and out_len <= 512);
var s: Self = undefined;
@ -277,7 +277,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
return s;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
mem.copy(u64, d.h[0..], iv[0..]);
// No key plus default parameters
@ -286,13 +286,13 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
d.buf_len = 0;
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Self.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var off: usize = 0;
// Partial buffer exists from previous update. Copy into buffer then hash.
@ -315,7 +315,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
d.buf_len += u8(b[off..].len);
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
mem.set(u8, d.buf[d.buf_len..], 0);
d.t += d.buf_len;
d.round(d.buf[0..], true);
@ -327,7 +327,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
}
}
fn round(d: &Self, b: []const u8, last: bool) {
fn round(d: &Self, b: []const u8, last: bool) void {
debug.assert(b.len == 128);
var m: [16]u64 = undefined;

View File

@ -10,7 +10,7 @@ const RoundParam = struct {
k: usize, s: u32, t: u32
};
fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) -> RoundParam {
fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam {
return RoundParam { .a = a, .b = b, .c = c, .d = d, .k = k, .s = s, .t = t };
}
@ -25,13 +25,13 @@ pub const Md5 = struct {
buf_len: u8,
total_len: u64,
pub fn init() -> Self {
pub fn init() Self {
var d: Self = undefined;
d.reset();
return d;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
d.s[0] = 0x67452301;
d.s[1] = 0xEFCDAB89;
d.s[2] = 0x98BADCFE;
@ -40,13 +40,13 @@ pub const Md5 = struct {
d.total_len = 0;
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Md5.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var off: usize = 0;
// Partial buffer exists from previous update. Copy into buffer then hash.
@ -71,7 +71,7 @@ pub const Md5 = struct {
d.total_len +%= b.len;
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
debug.assert(out.len >= 16);
// The buffer here will never be completely full.
@ -103,7 +103,7 @@ pub const Md5 = struct {
}
}
fn round(d: &Self, b: []const u8) {
fn round(d: &Self, b: []const u8) void {
debug.assert(b.len == 64);
var s: [16]u32 = undefined;

View File

@ -10,7 +10,7 @@ const RoundParam = struct {
a: usize, b: usize, c: usize, d: usize, e: usize, i: u32,
};
fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) -> RoundParam {
fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam {
return RoundParam { .a = a, .b = b, .c = c, .d = d, .e = e, .i = i };
}
@ -25,13 +25,13 @@ pub const Sha1 = struct {
buf_len: u8,
total_len: u64,
pub fn init() -> Self {
pub fn init() Self {
var d: Self = undefined;
d.reset();
return d;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
d.s[0] = 0x67452301;
d.s[1] = 0xEFCDAB89;
d.s[2] = 0x98BADCFE;
@ -41,13 +41,13 @@ pub const Sha1 = struct {
d.total_len = 0;
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Sha1.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var off: usize = 0;
// Partial buffer exists from previous update. Copy into buffer then hash.
@ -71,7 +71,7 @@ pub const Sha1 = struct {
d.total_len += b.len;
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
debug.assert(out.len >= 20);
// The buffer here will never be completely full.
@ -103,7 +103,7 @@ pub const Sha1 = struct {
}
}
fn round(d: &Self, b: []const u8) {
fn round(d: &Self, b: []const u8) void {
debug.assert(b.len == 64);
var s: [16]u32 = undefined;

View File

@ -13,7 +13,7 @@ const RoundParam256 = struct {
i: usize, k: u32,
};
fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) -> RoundParam256 {
fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 {
return RoundParam256 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
}
@ -56,7 +56,7 @@ const Sha256Params = Sha2Params32 {
pub const Sha224 = Sha2_32(Sha224Params);
pub const Sha256 = Sha2_32(Sha256Params);
fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
fn Sha2_32(comptime params: Sha2Params32) type { return struct {
const Self = this;
const block_size = 64;
const digest_size = params.out_len / 8;
@ -67,13 +67,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
buf_len: u8,
total_len: u64,
pub fn init() -> Self {
pub fn init() Self {
var d: Self = undefined;
d.reset();
return d;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
d.s[0] = params.iv0;
d.s[1] = params.iv1;
d.s[2] = params.iv2;
@ -86,13 +86,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
d.total_len = 0;
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Self.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var off: usize = 0;
// Partial buffer exists from previous update. Copy into buffer then hash.
@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
d.total_len += b.len;
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
debug.assert(out.len >= params.out_len / 8);
// The buffer here will never be completely full.
@ -151,7 +151,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
}
}
fn round(d: &Self, b: []const u8) {
fn round(d: &Self, b: []const u8) void {
debug.assert(b.len == 64);
var s: [64]u32 = undefined;
@ -329,7 +329,7 @@ const RoundParam512 = struct {
i: usize, k: u64,
};
fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) -> RoundParam512 {
fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 {
return RoundParam512 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
}
@ -372,7 +372,7 @@ const Sha512Params = Sha2Params64 {
pub const Sha384 = Sha2_64(Sha384Params);
pub const Sha512 = Sha2_64(Sha512Params);
fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
fn Sha2_64(comptime params: Sha2Params64) type { return struct {
const Self = this;
const block_size = 128;
const digest_size = params.out_len / 8;
@ -383,13 +383,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
buf_len: u8,
total_len: u128,
pub fn init() -> Self {
pub fn init() Self {
var d: Self = undefined;
d.reset();
return d;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
d.s[0] = params.iv0;
d.s[1] = params.iv1;
d.s[2] = params.iv2;
@ -402,13 +402,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
d.total_len = 0;
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Self.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var off: usize = 0;
// Partial buffer exists from previous update. Copy into buffer then hash.
@ -432,7 +432,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
d.total_len += b.len;
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
debug.assert(out.len >= params.out_len / 8);
// The buffer here will never be completely full.
@ -467,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
}
}
fn round(d: &Self, b: []const u8) {
fn round(d: &Self, b: []const u8) void {
debug.assert(b.len == 128);
var s: [80]u64 = undefined;

View File

@ -10,7 +10,7 @@ pub const Sha3_256 = Keccak(256, 0x06);
pub const Sha3_384 = Keccak(384, 0x06);
pub const Sha3_512 = Keccak(512, 0x06);
fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
fn Keccak(comptime bits: usize, comptime delim: u8) type { return struct {
const Self = this;
const block_size = 200;
const digest_size = bits / 8;
@ -19,25 +19,25 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
offset: usize,
rate: usize,
pub fn init() -> Self {
pub fn init() Self {
var d: Self = undefined;
d.reset();
return d;
}
pub fn reset(d: &Self) {
pub fn reset(d: &Self) void {
mem.set(u8, d.s[0..], 0);
d.offset = 0;
d.rate = 200 - (bits / 4);
}
pub fn hash(b: []const u8, out: []u8) {
pub fn hash(b: []const u8, out: []u8) void {
var d = Self.init();
d.update(b);
d.final(out);
}
pub fn update(d: &Self, b: []const u8) {
pub fn update(d: &Self, b: []const u8) void {
var ip: usize = 0;
var len = b.len;
var rate = d.rate - d.offset;
@ -62,7 +62,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
d.offset = offset + len;
}
pub fn final(d: &Self, out: []u8) {
pub fn final(d: &Self, out: []u8) void {
// padding
d.s[d.offset] ^= delim;
d.s[d.rate - 1] ^= 0x80;
@ -109,7 +109,7 @@ const M5 = []const usize {
0, 1, 2, 3, 4, 0, 1, 2, 3, 4
};
fn keccak_f(comptime F: usize, d: []u8) {
fn keccak_f(comptime F: usize, d: []u8) void {
debug.assert(d.len == F / 8);
const B = F / 25;

View File

@ -3,7 +3,7 @@ const mem = @import("../mem.zig");
const fmt = @import("../fmt/index.zig");
// Hash using the specified hasher `H` asserting `expected == H(input)`.
pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, input: []const u8) {
pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, input: []const u8) void {
var h: [expected.len / 2]u8 = undefined;
Hasher.hash(input, h[0..]);
@ -11,7 +11,7 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu
}
// Assert `expected` == `input` where `input` is a bytestring.
pub fn assertEqual(comptime expected: []const u8, input: []const u8) {
pub fn assertEqual(comptime expected: []const u8, input: []const u8) void {
var expected_bytes: [expected.len / 2]u8 = undefined;
for (expected_bytes) |*r, i| {
*r = fmt.parseInt(u8, expected[2*i .. 2*i+2], 16) catch unreachable;

View File

@ -18,7 +18,7 @@ const c = @cImport({
const Mb = 1024 * 1024;
pub fn main() -> %void {
pub fn main() %void {
var stdout_file = try std.io.getStdOut();
var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
const stdout = &stdout_out_stream.stream;

View File

@ -3,13 +3,13 @@ const debug = std.debug;
const mem = std.mem;
const assert = debug.assert;
pub fn len(ptr: &const u8) -> usize {
pub fn len(ptr: &const u8) usize {
var count: usize = 0;
while (ptr[count] != 0) : (count += 1) {}
return count;
}
pub fn cmp(a: &const u8, b: &const u8) -> i8 {
pub fn cmp(a: &const u8, b: &const u8) i8 {
var index: usize = 0;
while (a[index] == b[index] and a[index] != 0) : (index += 1) {}
if (a[index] > b[index]) {
@ -21,11 +21,11 @@ pub fn cmp(a: &const u8, b: &const u8) -> i8 {
}
}
pub fn toSliceConst(str: &const u8) -> []const u8 {
pub fn toSliceConst(str: &const u8) []const u8 {
return str[0..len(str)];
}
pub fn toSlice(str: &u8) -> []u8 {
pub fn toSlice(str: &u8) []u8 {
return str[0..len(str)];
}
@ -34,7 +34,7 @@ test "cstr fns" {
testCStrFnsImpl();
}
fn testCStrFnsImpl() {
fn testCStrFnsImpl() void {
assert(cmp(c"aoeu", c"aoez") == -1);
assert(len(c"123456789") == 9);
}
@ -42,7 +42,7 @@ fn testCStrFnsImpl() {
/// Returns a mutable slice with exactly the same size which is guaranteed to
/// have a null byte after it.
/// Caller owns the returned memory.
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) %[]u8 {
const result = try allocator.alloc(u8, slice.len + 1);
mem.copy(u8, result, slice);
result[slice.len] = 0;
@ -56,7 +56,7 @@ pub const NullTerminated2DArray = struct {
/// Takes N lists of strings, concatenates the lists together, and adds a null terminator
/// Caller must deinit result
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) -> %NullTerminated2DArray {
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) %NullTerminated2DArray {
var new_len: usize = 1; // 1 for the list null
var byte_count: usize = 0;
for (slices) |slice| {
@ -71,7 +71,7 @@ pub const NullTerminated2DArray = struct {
byte_count += index_size;
const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
%defer allocator.free(buf);
errdefer allocator.free(buf);
var write_index = index_size;
const index_buf = ([]?&u8)(buf);
@ -96,7 +96,7 @@ pub const NullTerminated2DArray = struct {
};
}
pub fn deinit(self: &NullTerminated2DArray) {
pub fn deinit(self: &NullTerminated2DArray) void {
const buf = @ptrCast(&u8, self.ptr);
self.allocator.free(buf[0..self.byte_count]);
}

View File

@ -12,7 +12,7 @@ pub const FailingAllocator = struct {
freed_bytes: usize,
deallocations: usize,
pub fn init(allocator: &mem.Allocator, fail_index: usize) -> FailingAllocator {
pub fn init(allocator: &mem.Allocator, fail_index: usize) FailingAllocator {
return FailingAllocator {
.internal_allocator = allocator,
.fail_index = fail_index,
@ -28,7 +28,7 @@ pub const FailingAllocator = struct {
};
}
fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 {
fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) %[]u8 {
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
if (self.index == self.fail_index) {
return error.OutOfMemory;
@ -39,7 +39,7 @@ pub const FailingAllocator = struct {
return result;
}
fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {
fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
if (new_size <= old_mem.len) {
self.freed_bytes += old_mem.len - new_size;
@ -55,7 +55,7 @@ pub const FailingAllocator = struct {
return result;
}
fn free(allocator: &mem.Allocator, bytes: []u8) {
fn free(allocator: &mem.Allocator, bytes: []u8) void {
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
self.freed_bytes += bytes.len;
self.deallocations += 1;

View File

@ -25,11 +25,11 @@ error TodoSupportCOFFDebugInfo;
var stderr_file: io.File = undefined;
var stderr_file_out_stream: io.FileOutStream = undefined;
var stderr_stream: ?&io.OutStream = null;
pub fn warn(comptime fmt: []const u8, args: ...) {
pub fn warn(comptime fmt: []const u8, args: ...) void {
const stderr = getStderrStream() catch return;
stderr.print(fmt, args) catch return;
}
fn getStderrStream() -> %&io.OutStream {
fn getStderrStream() %&io.OutStream {
if (stderr_stream) |st| {
return st;
} else {
@ -42,7 +42,7 @@ fn getStderrStream() -> %&io.OutStream {
}
var self_debug_info: ?&ElfStackTrace = null;
pub fn getSelfDebugInfo() -> %&ElfStackTrace {
pub fn getSelfDebugInfo() %&ElfStackTrace {
if (self_debug_info) |info| {
return info;
} else {
@ -53,7 +53,7 @@ pub fn getSelfDebugInfo() -> %&ElfStackTrace {
}
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
pub fn dumpCurrentStackTrace() {
pub fn dumpCurrentStackTrace() void {
const stderr = getStderrStream() catch return;
const debug_info = getSelfDebugInfo() catch |err| {
stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;
@ -67,7 +67,7 @@ pub fn dumpCurrentStackTrace() {
}
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) {
pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) void {
const stderr = getStderrStream() catch return;
const debug_info = getSelfDebugInfo() catch |err| {
stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;
@ -85,7 +85,7 @@ pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) {
/// generated, and the `unreachable` statement triggers a panic.
/// In ReleaseFast and ReleaseSmall modes, calls to this function can be
/// optimized away.
pub fn assert(ok: bool) {
pub fn assert(ok: bool) void {
if (!ok) {
// In ReleaseFast test mode, we still want assert(false) to crash, so
// we insert an explicit call to @panic instead of unreachable.
@ -100,7 +100,7 @@ pub fn assert(ok: bool) {
/// Call this function when you want to panic if the condition is not true.
/// If `ok` is `false`, this function will panic in every release mode.
pub fn assertOrPanic(ok: bool) {
pub fn assertOrPanic(ok: bool) void {
if (!ok) {
@panic("assertion failure");
}
@ -108,7 +108,7 @@ pub fn assertOrPanic(ok: bool) {
var panicking = false;
/// This is the default panic implementation.
pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
pub fn panic(comptime format: []const u8, args: ...) noreturn {
// TODO an intrinsic that labels this as unlikely to be reached
// TODO
@ -130,7 +130,7 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
os.abort();
}
pub fn panicWithTrace(trace: &const builtin.StackTrace, comptime format: []const u8, args: ...) -> noreturn {
pub fn panicWithTrace(trace: &const builtin.StackTrace, comptime format: []const u8, args: ...) noreturn {
if (panicking) {
os.abort();
} else {
@ -153,7 +153,7 @@ error PathNotFound;
error InvalidDebugInfo;
pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator,
debug_info: &ElfStackTrace, tty_color: bool) -> %void
debug_info: &ElfStackTrace, tty_color: bool) %void
{
var frame_index: usize = undefined;
var frames_left: usize = undefined;
@ -175,7 +175,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.O
}
pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator,
debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) -> %void
debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) %void
{
var ignored_count: usize = 0;
@ -191,7 +191,7 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat
}
}
fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) -> %void {
fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) %void {
if (builtin.os == builtin.Os.windows) {
return error.UnsupportedDebugInfo;
}
@ -232,7 +232,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a
}
}
pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
pub fn openSelfDebugInfo(allocator: &mem.Allocator) %&ElfStackTrace {
switch (builtin.object_format) {
builtin.ObjectFormat.elf => {
const st = try allocator.create(ElfStackTrace);
@ -248,10 +248,10 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
.compile_unit_list = ArrayList(CompileUnit).init(allocator),
};
st.self_exe_file = try os.openSelfExe();
%defer st.self_exe_file.close();
errdefer st.self_exe_file.close();
try st.elf.openFile(allocator, &st.self_exe_file);
%defer st.elf.close();
errdefer st.elf.close();
st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;
st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
@ -276,7 +276,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
}
}
fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) -> %void {
fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) %void {
var f = try io.File.openRead(line_info.file_name, allocator);
defer f.close();
// TODO fstat and make sure that the file has the correct size
@ -320,17 +320,17 @@ pub const ElfStackTrace = struct {
abbrev_table_list: ArrayList(AbbrevTableHeader),
compile_unit_list: ArrayList(CompileUnit),
pub fn allocator(self: &const ElfStackTrace) -> &mem.Allocator {
pub fn allocator(self: &const ElfStackTrace) &mem.Allocator {
return self.abbrev_table_list.allocator;
}
pub fn readString(self: &ElfStackTrace) -> %[]u8 {
pub fn readString(self: &ElfStackTrace) %[]u8 {
var in_file_stream = io.FileInStream.init(&self.self_exe_file);
const in_stream = &in_file_stream.stream;
return readStringRaw(self.allocator(), in_stream);
}
pub fn close(self: &ElfStackTrace) {
pub fn close(self: &ElfStackTrace) void {
self.self_exe_file.close();
self.elf.close();
}
@ -387,7 +387,7 @@ const Constant = struct {
payload: []u8,
signed: bool,
fn asUnsignedLe(self: &const Constant) -> %u64 {
fn asUnsignedLe(self: &const Constant) %u64 {
if (self.payload.len > @sizeOf(u64))
return error.InvalidDebugInfo;
if (self.signed)
@ -406,7 +406,7 @@ const Die = struct {
value: FormValue,
};
fn getAttr(self: &const Die, id: u64) -> ?&const FormValue {
fn getAttr(self: &const Die, id: u64) ?&const FormValue {
for (self.attrs.toSliceConst()) |*attr| {
if (attr.id == id)
return &attr.value;
@ -414,7 +414,7 @@ const Die = struct {
return null;
}
fn getAttrAddr(self: &const Die, id: u64) -> %u64 {
fn getAttrAddr(self: &const Die, id: u64) %u64 {
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
return switch (*form_value) {
FormValue.Address => |value| value,
@ -422,7 +422,7 @@ const Die = struct {
};
}
fn getAttrSecOffset(self: &const Die, id: u64) -> %u64 {
fn getAttrSecOffset(self: &const Die, id: u64) %u64 {
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
return switch (*form_value) {
FormValue.Const => |value| value.asUnsignedLe(),
@ -431,7 +431,7 @@ const Die = struct {
};
}
fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {
fn getAttrUnsignedLe(self: &const Die, id: u64) %u64 {
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
return switch (*form_value) {
FormValue.Const => |value| value.asUnsignedLe(),
@ -439,7 +439,7 @@ const Die = struct {
};
}
fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {
fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) %[]u8 {
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
return switch (*form_value) {
FormValue.String => |value| value,
@ -462,7 +462,7 @@ const LineInfo = struct {
file_name: []u8,
allocator: &mem.Allocator,
fn deinit(self: &const LineInfo) {
fn deinit(self: &const LineInfo) void {
self.allocator.free(self.file_name);
}
};
@ -489,7 +489,7 @@ const LineNumberProgram = struct {
prev_end_sequence: bool,
pub fn init(is_stmt: bool, include_dirs: []const []const u8,
file_entries: &ArrayList(FileEntry), target_address: usize) -> LineNumberProgram
file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram
{
return LineNumberProgram {
.address = 0,
@ -512,7 +512,7 @@ const LineNumberProgram = struct {
};
}
pub fn checkLineMatch(self: &LineNumberProgram) -> %?LineInfo {
pub fn checkLineMatch(self: &LineNumberProgram) %?LineInfo {
if (self.target_address >= self.prev_address and self.target_address < self.address) {
const file_entry = if (self.prev_file == 0) {
return error.MissingDebugInfo;
@ -524,7 +524,7 @@ const LineNumberProgram = struct {
return error.InvalidDebugInfo;
} else self.include_dirs[file_entry.dir_index];
const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
%defer self.file_entries.allocator.free(file_name);
errdefer self.file_entries.allocator.free(file_name);
return LineInfo {
.line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
.column = self.prev_column,
@ -544,7 +544,7 @@ const LineNumberProgram = struct {
}
};
fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {
fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) %[]u8 {
var buf = ArrayList(u8).init(allocator);
while (true) {
const byte = try in_stream.readByte();
@ -555,58 +555,58 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {
return buf.toSlice();
}
fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 {
fn getString(st: &ElfStackTrace, offset: u64) %[]u8 {
const pos = st.debug_str.offset + offset;
try st.self_exe_file.seekTo(pos);
return st.readString();
}
fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %[]u8 {
fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %[]u8 {
const buf = try global_allocator.alloc(u8, size);
%defer global_allocator.free(buf);
errdefer global_allocator.free(buf);
if ((try in_stream.read(buf)) < size) return error.EndOfFile;
return buf;
}
fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {
const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue { .Block = buf };
}
fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {
const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);
return parseFormValueBlockLen(allocator, in_stream, block_len);
}
fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue {
fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) %FormValue {
return FormValue { .Const = Constant {
.signed = signed,
.payload = try readAllocBytes(allocator, in_stream, size),
}};
}
fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 {
fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) %u64 {
return if (is_64) try in_stream.readIntLe(u64)
else u64(try in_stream.readIntLe(u32)) ;
}
fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {
fn parseFormValueTargetAddrSize(in_stream: &io.InStream) %u64 {
return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))
else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
else unreachable;
}
fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {
const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue { .Ref = buf };
}
fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue {
fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) %FormValue {
const block_len = try in_stream.readIntLe(T);
return parseFormValueRefLen(allocator, in_stream, block_len);
}
fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue {
fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) %FormValue {
return switch (form_id) {
DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },
DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
@ -656,7 +656,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
};
}
fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
fn parseAbbrevTable(st: &ElfStackTrace) %AbbrevTable {
const in_file = &st.self_exe_file;
var in_file_stream = io.FileInStream.init(in_file);
const in_stream = &in_file_stream.stream;
@ -688,7 +688,7 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,
/// seeks in the stream and parses it.
fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable {
fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) %&const AbbrevTable {
for (st.abbrev_table_list.toSlice()) |*header| {
if (header.offset == abbrev_offset) {
return &header.table;
@ -702,7 +702,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable
return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table;
}
fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&const AbbrevTableEntry {
fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {
for (abbrev_table.toSliceConst()) |*table_entry| {
if (table_entry.abbrev_code == abbrev_code)
return table_entry;
@ -710,7 +710,7 @@ fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&
return null;
}
fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -> %Die {
fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) %Die {
const in_file = &st.self_exe_file;
var in_file_stream = io.FileInStream.init(in_file);
const in_stream = &in_file_stream.stream;
@ -732,7 +732,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -
return result;
}
fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) -> %LineInfo {
fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) %LineInfo {
const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);
const in_file = &st.self_exe_file;
@ -910,7 +910,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
return error.MissingDebugInfo;
}
fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
fn scanAllCompileUnits(st: &ElfStackTrace) %void {
const debug_info_end = st.debug_info.offset + st.debug_info.size;
var this_unit_offset = st.debug_info.offset;
var cu_index: usize = 0;
@ -986,7 +986,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
}
}
fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUnit {
fn findCompileUnit(st: &ElfStackTrace, target_address: u64) %&const CompileUnit {
var in_file_stream = io.FileInStream.init(&st.self_exe_file);
const in_stream = &in_file_stream.stream;
for (st.compile_unit_list.toSlice()) |*compile_unit| {
@ -1022,7 +1022,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
return error.MissingDebugInfo;
}
fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
fn readInitialLength(in_stream: &io.InStream, is_64: &bool) %u64 {
const first_32_bits = try in_stream.readIntLe(u32);
*is_64 = (first_32_bits == 0xffffffff);
if (*is_64) {
@ -1033,7 +1033,7 @@ fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
}
}
fn readULeb128(in_stream: &io.InStream) -> %u64 {
fn readULeb128(in_stream: &io.InStream) %u64 {
var result: u64 = 0;
var shift: usize = 0;
@ -1054,7 +1054,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 {
}
}
fn readILeb128(in_stream: &io.InStream) -> %i64 {
fn readILeb128(in_stream: &io.InStream) %i64 {
var result: i64 = 0;
var shift: usize = 0;

View File

@ -81,14 +81,14 @@ pub const Elf = struct {
prealloc_file: io.File,
/// Call close when done.
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) -> %void {
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) %void {
try elf.prealloc_file.open(path);
try elf.openFile(allocator, &elf.prealloc_file);
elf.auto_close_stream = true;
}
/// Call close when done.
pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) -> %void {
pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) %void {
elf.allocator = allocator;
elf.in_file = file;
elf.auto_close_stream = false;
@ -183,7 +183,7 @@ pub const Elf = struct {
try elf.in_file.seekTo(elf.section_header_offset);
elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count);
%defer elf.allocator.free(elf.section_headers);
errdefer elf.allocator.free(elf.section_headers);
if (elf.is_64) {
if (sh_entry_size != 64) return error.InvalidFormat;
@ -232,14 +232,14 @@ pub const Elf = struct {
}
}
pub fn close(elf: &Elf) {
pub fn close(elf: &Elf) void {
elf.allocator.free(elf.section_headers);
if (elf.auto_close_stream)
elf.in_file.close();
}
pub fn findSection(elf: &Elf, name: []const u8) -> %?&SectionHeader {
pub fn findSection(elf: &Elf, name: []const u8) %?&SectionHeader {
var file_stream = io.FileInStream.init(elf.in_file);
const in = &file_stream.stream;
@ -263,7 +263,7 @@ pub const Elf = struct {
return null;
}
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void {
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) %void {
try elf.in_file.seekTo(elf_section.offset);
}
};

View File

@ -1,19 +1,19 @@
const mem = @import("mem.zig");
const builtin = @import("builtin");
pub fn swapIfLe(comptime T: type, x: T) -> T {
pub fn swapIfLe(comptime T: type, x: T) T {
return swapIf(builtin.Endian.Little, T, x);
}
pub fn swapIfBe(comptime T: type, x: T) -> T {
pub fn swapIfBe(comptime T: type, x: T) T {
return swapIf(builtin.Endian.Big, T, x);
}
pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T {
pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) T {
return if (builtin.endian == endian) swap(T, x) else x;
}
pub fn swap(comptime T: type, x: T) -> T {
pub fn swap(comptime T: type, x: T) T {
var buf: [@sizeOf(T)]u8 = undefined;
mem.writeInt(buf[0..], x, builtin.Endian.Little);
return mem.readInt(buf, T, builtin.Endian.Big);

View File

@ -438,7 +438,7 @@ const Slab = struct {
exp: i32,
};
fn slab(str: []const u8, exp: i32) -> Slab {
fn slab(str: []const u8, exp: i32) Slab {
return Slab {
.str = str,
.exp = exp,

View File

@ -13,7 +13,7 @@ pub const FloatDecimal = struct {
};
/// Corrected Errol3 double to ASCII conversion.
pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
pub fn errol3(value: f64, buffer: []u8) FloatDecimal {
const bits = @bitCast(u64, value);
const i = tableLowerBound(bits);
if (i < enum3.len and enum3[i] == bits) {
@ -30,7 +30,7 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
}
/// Uncorrected Errol3 double to ASCII conversion.
fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
fn errol3u(val: f64, buffer: []u8) FloatDecimal {
// check if in integer or fixed range
if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
@ -133,7 +133,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
};
}
fn tableLowerBound(k: u64) -> usize {
fn tableLowerBound(k: u64) usize {
var i = enum3.len;
var j: usize = 0;
@ -153,7 +153,7 @@ fn tableLowerBound(k: u64) -> usize {
/// @in: The HP number.
/// @val: The double.
/// &returns: The HP number.
fn hpProd(in: &const HP, val: f64) -> HP {
fn hpProd(in: &const HP, val: f64) HP {
var hi: f64 = undefined;
var lo: f64 = undefined;
split(in.val, &hi, &lo);
@ -175,12 +175,12 @@ fn hpProd(in: &const HP, val: f64) -> HP {
/// @val: The double.
/// @hi: The high bits.
/// @lo: The low bits.
fn split(val: f64, hi: &f64, lo: &f64) {
fn split(val: f64, hi: &f64, lo: &f64) void {
*hi = gethi(val);
*lo = val - *hi;
}
fn gethi(in: f64) -> f64 {
fn gethi(in: f64) f64 {
const bits = @bitCast(u64, in);
const new_bits = bits & 0xFFFFFFFFF8000000;
return @bitCast(f64, new_bits);
@ -188,7 +188,7 @@ fn gethi(in: f64) -> f64 {
/// Normalize the number by factoring in the error.
/// @hp: The float pair.
fn hpNormalize(hp: &HP) {
fn hpNormalize(hp: &HP) void {
const val = hp.val;
hp.val += hp.off;
@ -197,7 +197,7 @@ fn hpNormalize(hp: &HP) {
/// Divide the high-precision number by ten.
/// @hp: The high-precision number
fn hpDiv10(hp: &HP) {
fn hpDiv10(hp: &HP) void {
var val = hp.val;
hp.val /= 10.0;
@ -213,7 +213,7 @@ fn hpDiv10(hp: &HP) {
/// Multiply the high-precision number by ten.
/// @hp: The high-precision number
fn hpMul10(hp: &HP) {
fn hpMul10(hp: &HP) void {
const val = hp.val;
hp.val *= 10.0;
@ -233,7 +233,7 @@ fn hpMul10(hp: &HP) {
/// @val: The val.
/// @buf: The output buffer.
/// &return: The exponent.
fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
fn errolInt(val: f64, buffer: []u8) FloatDecimal {
const pow19 = u128(1e19);
assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
@ -291,7 +291,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
/// @val: The val.
/// @buf: The output buffer.
/// &return: The exponent.
fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
fn errolFixed(val: f64, buffer: []u8) FloatDecimal {
assert((val >= 16.0) and (val < 9.007199254740992e15));
const u = u64(val);
@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
};
}
fn fpnext(val: f64) -> f64 {
fn fpnext(val: f64) f64 {
return @bitCast(f64, @bitCast(u64, val) +% 1);
}
fn fpprev(val: f64) -> f64 {
fn fpprev(val: f64) f64 {
return @bitCast(f64, @bitCast(u64, val) -% 1);
}
@ -373,7 +373,7 @@ pub const c_digits_lut = []u8 {
'9', '8', '9', '9',
};
fn u64toa(value_param: u64, buffer: []u8) -> usize {
fn u64toa(value_param: u64, buffer: []u8) usize {
var value = value_param;
const kTen8: u64 = 100000000;
const kTen9: u64 = kTen8 * 10;
@ -606,7 +606,7 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
return buf_index;
}
fn fpeint(from: f64) -> u128 {
fn fpeint(from: f64) u128 {
const bits = @bitCast(u64, from);
assert((bits & ((1 << 52) - 1)) == 0);
@ -621,7 +621,7 @@ fn fpeint(from: f64) -> u128 {
/// @a: Integer a.
/// @b: Integer b.
/// &returns: An index within [0, 19).
fn mismatch10(a: u64, b: u64) -> i32 {
fn mismatch10(a: u64, b: u64) i32 {
const pow10 = 10000000000;
const af = a / pow10;
const bf = b / pow10;

View File

@ -24,8 +24,8 @@ const State = enum { // TODO put inside format function and make sure the name a
/// Renders fmt string with args, calling output with slices of bytes.
/// If `output` returns an error, the error is returned from `format` and
/// `output` is not called again.
pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
comptime fmt: []const u8, args: ...) -> %void
pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
comptime fmt: []const u8, args: ...) %void
{
comptime var start_index = 0;
comptime var state = State.Start;
@ -191,7 +191,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
}
}
pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {
pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
const T = @typeOf(value);
switch (@typeId(T)) {
builtin.TypeId.Int => {
@ -240,12 +240,12 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
}
}
pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {
pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
return output(context, (&c)[0..1]);
}
pub fn formatBuf(buf: []const u8, width: usize,
context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
context: var, output: fn(@typeOf(context), []const u8)%void) %void
{
try output(context, buf);
@ -256,7 +256,7 @@ pub fn formatBuf(buf: []const u8, width: usize,
}
}
pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {
pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
var x = f64(value);
// Errol doesn't handle these special cases.
@ -294,7 +294,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
}
}
pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {
pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
var x = f64(value);
// Errol doesn't handle these special cases.
@ -336,7 +336,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
context: var, output: fn(@typeOf(context), []const u8)%void) %void
{
if (@typeOf(value).is_signed) {
return formatIntSigned(value, base, uppercase, width, context, output);
@ -346,7 +346,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
}
fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
context: var, output: fn(@typeOf(context), []const u8)%void) %void
{
const uint = @IntType(false, @typeOf(value).bit_count);
if (value < 0) {
@ -367,7 +367,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
}
fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
context: var, output: fn(@typeOf(context), []const u8)%void) %void
{
// max_int_digits accounts for the minus sign. when printing an unsigned
// number we don't need to do that.
@ -405,7 +405,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
}
}
pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> usize {
pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) usize {
var context = FormatIntBuf {
.out_buf = out_buf,
.index = 0,
@ -417,12 +417,12 @@ const FormatIntBuf = struct {
out_buf: []u8,
index: usize,
};
fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) -> %void {
fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) %void {
mem.copy(u8, context.out_buf[context.index..], bytes);
context.index += bytes.len;
}
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) -> %T {
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) %T {
if (!T.is_signed)
return parseUnsigned(T, buf, radix);
if (buf.len == 0)
@ -446,7 +446,7 @@ test "fmt.parseInt" {
assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
}
pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) %T {
var x: T = 0;
for (buf) |c| {
@ -459,7 +459,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
}
error InvalidChar;
fn charToDigit(c: u8, radix: u8) -> %u8 {
fn charToDigit(c: u8, radix: u8) %u8 {
const value = switch (c) {
'0' ... '9' => c - '0',
'A' ... 'Z' => c - 'A' + 10,
@ -473,7 +473,7 @@ fn charToDigit(c: u8, radix: u8) -> %u8 {
return value;
}
fn digitToChar(digit: u8, uppercase: bool) -> u8 {
fn digitToChar(digit: u8, uppercase: bool) u8 {
return switch (digit) {
0 ... 9 => digit + '0',
10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
@ -486,19 +486,19 @@ const BufPrintContext = struct {
};
error BufferTooSmall;
fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void {
fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) %void {
if (context.remaining.len < bytes.len) return error.BufferTooSmall;
mem.copy(u8, context.remaining, bytes);
context.remaining = context.remaining[bytes.len..];
}
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 {
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) %[]u8 {
var context = BufPrintContext { .remaining = buf, };
try format(&context, bufPrintWrite, fmt, args);
return buf[0..buf.len - context.remaining.len];
}
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 {
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) %[]u8 {
var size: usize = 0;
// Cannot fail because `countSize` cannot fail.
format(&size, countSize, fmt, args) catch unreachable;
@ -506,7 +506,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...
return bufPrint(buf, fmt, args);
}
fn countSize(size: &usize, bytes: []const u8) -> %void {
fn countSize(size: &usize, bytes: []const u8) %void {
*size += bytes.len;
}
@ -528,7 +528,7 @@ test "buf print int" {
assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
}
fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> []u8 {
fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) []u8 {
return buf[0..formatIntBuf(buf, value, base, uppercase, width)];
}
@ -644,7 +644,7 @@ test "fmt.format" {
}
}
pub fn trim(buf: []const u8) -> []const u8 {
pub fn trim(buf: []const u8) []const u8 {
var start: usize = 0;
while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) { }
@ -671,7 +671,7 @@ test "fmt.trim" {
assert(mem.eql(u8, "abc", trim("abc ")));
}
pub fn isWhiteSpace(byte: u8) -> bool {
pub fn isWhiteSpace(byte: u8) bool {
return switch (byte) {
' ', '\t', '\n', '\r' => true,
else => false,

View File

@ -10,8 +10,8 @@ const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;
const debug_u32 = if (want_modification_safety) u32 else void;
pub fn HashMap(comptime K: type, comptime V: type,
comptime hash: fn(key: K)->u32,
comptime eql: fn(a: K, b: K)->bool) -> type
comptime hash: fn(key: K)u32,
comptime eql: fn(a: K, b: K)bool) type
{
return struct {
entries: []Entry,
@ -39,7 +39,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
// used to detect concurrent modification
initial_modification_count: debug_u32,
pub fn next(it: &Iterator) -> ?&Entry {
pub fn next(it: &Iterator) ?&Entry {
if (want_modification_safety) {
assert(it.initial_modification_count == it.hm.modification_count); // concurrent modification
}
@ -56,7 +56,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
}
};
pub fn init(allocator: &Allocator) -> Self {
pub fn init(allocator: &Allocator) Self {
return Self {
.entries = []Entry{},
.allocator = allocator,
@ -66,11 +66,11 @@ pub fn HashMap(comptime K: type, comptime V: type,
};
}
pub fn deinit(hm: &Self) {
pub fn deinit(hm: &Self) void {
hm.allocator.free(hm.entries);
}
pub fn clear(hm: &Self) {
pub fn clear(hm: &Self) void {
for (hm.entries) |*entry| {
entry.used = false;
}
@ -80,7 +80,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
}
/// Returns the value that was already there.
pub fn put(hm: &Self, key: K, value: &const V) -> %?V {
pub fn put(hm: &Self, key: K, value: &const V) %?V {
if (hm.entries.len == 0) {
try hm.initCapacity(16);
}
@ -102,18 +102,18 @@ pub fn HashMap(comptime K: type, comptime V: type,
return hm.internalPut(key, value);
}
pub fn get(hm: &Self, key: K) -> ?&Entry {
pub fn get(hm: &Self, key: K) ?&Entry {
if (hm.entries.len == 0) {
return null;
}
return hm.internalGet(key);
}
pub fn contains(hm: &Self, key: K) -> bool {
pub fn contains(hm: &Self, key: K) bool {
return hm.get(key) != null;
}
pub fn remove(hm: &Self, key: K) -> ?&Entry {
pub fn remove(hm: &Self, key: K) ?&Entry {
hm.incrementModificationCount();
const start_index = hm.keyToIndex(key);
{var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
@ -142,7 +142,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
return null;
}
pub fn iterator(hm: &const Self) -> Iterator {
pub fn iterator(hm: &const Self) Iterator {
return Iterator {
.hm = hm,
.count = 0,
@ -151,7 +151,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
};
}
fn initCapacity(hm: &Self, capacity: usize) -> %void {
fn initCapacity(hm: &Self, capacity: usize) %void {
hm.entries = try hm.allocator.alloc(Entry, capacity);
hm.size = 0;
hm.max_distance_from_start_index = 0;
@ -160,14 +160,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
}
}
fn incrementModificationCount(hm: &Self) {
fn incrementModificationCount(hm: &Self) void {
if (want_modification_safety) {
hm.modification_count +%= 1;
}
}
/// Returns the value that was already there.
fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) -> ?V {
fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) ?V {
var key = orig_key;
var value = *orig_value;
const start_index = hm.keyToIndex(key);
@ -217,7 +217,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
unreachable; // put into a full map
}
fn internalGet(hm: &Self, key: K) -> ?&Entry {
fn internalGet(hm: &Self, key: K) ?&Entry {
const start_index = hm.keyToIndex(key);
{var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
const index = (start_index + roll_over) % hm.entries.len;
@ -229,7 +229,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
return null;
}
fn keyToIndex(hm: &Self, key: K) -> usize {
fn keyToIndex(hm: &Self, key: K) usize {
return usize(hash(key)) % hm.entries.len;
}
};
@ -254,10 +254,10 @@ test "basicHashMapTest" {
assert(map.get(2) == null);
}
fn hash_i32(x: i32) -> u32 {
fn hash_i32(x: i32) u32 {
return @bitCast(u32, x);
}
fn eql_i32(a: i32, b: i32) -> bool {
fn eql_i32(a: i32, b: i32) bool {
return a == b;
}

View File

@ -18,14 +18,14 @@ var c_allocator_state = Allocator {
.freeFn = cFree,
};
fn cAlloc(self: &Allocator, n: usize, alignment: u29) -> %[]u8 {
fn cAlloc(self: &Allocator, n: usize, alignment: u29) %[]u8 {
return if (c.malloc(usize(n))) |buf|
@ptrCast(&u8, buf)[0..n]
else
error.OutOfMemory;
}
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
const old_ptr = @ptrCast(&c_void, old_mem.ptr);
if (c.realloc(old_ptr, new_size)) |buf| {
return @ptrCast(&u8, buf)[0..new_size];
@ -36,7 +36,7 @@ fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ->
}
}
fn cFree(self: &Allocator, old_mem: []u8) {
fn cFree(self: &Allocator, old_mem: []u8) void {
const old_ptr = @ptrCast(&c_void, old_mem.ptr);
c.free(old_ptr);
}
@ -47,7 +47,7 @@ pub const IncrementingAllocator = struct {
end_index: usize,
heap_handle: if (builtin.os == Os.windows) os.windows.HANDLE else void,
fn init(capacity: usize) -> %IncrementingAllocator {
fn init(capacity: usize) %IncrementingAllocator {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const p = os.posix;
@ -85,7 +85,7 @@ pub const IncrementingAllocator = struct {
}
}
fn deinit(self: &IncrementingAllocator) {
fn deinit(self: &IncrementingAllocator) void {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
_ = os.posix.munmap(self.bytes.ptr, self.bytes.len);
@ -97,15 +97,15 @@ pub const IncrementingAllocator = struct {
}
}
fn reset(self: &IncrementingAllocator) {
fn reset(self: &IncrementingAllocator) void {
self.end_index = 0;
}
fn bytesLeft(self: &const IncrementingAllocator) -> usize {
fn bytesLeft(self: &const IncrementingAllocator) usize {
return self.bytes.len - self.end_index;
}
fn alloc(allocator: &Allocator, n: usize, alignment: u29) -> %[]u8 {
fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
const addr = @ptrToInt(&self.bytes[self.end_index]);
const rem = @rem(addr, alignment);
@ -120,7 +120,7 @@ pub const IncrementingAllocator = struct {
return result;
}
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
if (new_size <= old_mem.len) {
return old_mem[0..new_size];
} else {
@ -130,7 +130,7 @@ pub const IncrementingAllocator = struct {
}
}
fn free(allocator: &Allocator, bytes: []u8) {
fn free(allocator: &Allocator, bytes: []u8) void {
// Do nothing. That's the point of an incrementing allocator.
}
};

View File

@ -48,8 +48,9 @@ error PathNotFound;
error OutOfMemory;
error Unseekable;
error EndOfFile;
error FilePosLargerThanPointerRange;
pub fn getStdErr() -> %File {
pub fn getStdErr() %File {
const handle = if (is_windows)
try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
else if (is_posix)
@ -59,7 +60,7 @@ pub fn getStdErr() -> %File {
return File.openHandle(handle);
}
pub fn getStdOut() -> %File {
pub fn getStdOut() %File {
const handle = if (is_windows)
try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
else if (is_posix)
@ -69,7 +70,7 @@ pub fn getStdOut() -> %File {
return File.openHandle(handle);
}
pub fn getStdIn() -> %File {
pub fn getStdIn() %File {
const handle = if (is_windows)
try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
else if (is_posix)
@ -84,7 +85,7 @@ pub const FileInStream = struct {
file: &File,
stream: InStream,
pub fn init(file: &File) -> FileInStream {
pub fn init(file: &File) FileInStream {
return FileInStream {
.file = file,
.stream = InStream {
@ -93,7 +94,7 @@ pub const FileInStream = struct {
};
}
fn readFn(in_stream: &InStream, buffer: []u8) -> %usize {
fn readFn(in_stream: &InStream, buffer: []u8) %usize {
const self = @fieldParentPtr(FileInStream, "stream", in_stream);
return self.file.read(buffer);
}
@ -104,7 +105,7 @@ pub const FileOutStream = struct {
file: &File,
stream: OutStream,
pub fn init(file: &File) -> FileOutStream {
pub fn init(file: &File) FileOutStream {
return FileOutStream {
.file = file,
.stream = OutStream {
@ -113,7 +114,7 @@ pub const FileOutStream = struct {
};
}
fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
const self = @fieldParentPtr(FileOutStream, "stream", out_stream);
return self.file.write(bytes);
}
@ -128,7 +129,7 @@ pub const File = struct {
/// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
/// Call close to clean up.
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) -> %File {
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) %File {
if (is_posix) {
const flags = system.O_LARGEFILE|system.O_RDONLY;
const fd = try os.posixOpen(path, flags, 0, allocator);
@ -143,7 +144,7 @@ pub const File = struct {
}
/// Calls `openWriteMode` with 0o666 for the mode.
pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) -> %File {
pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) %File {
return openWriteMode(path, 0o666, allocator);
}
@ -153,7 +154,7 @@ pub const File = struct {
/// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
/// Call close to clean up.
pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) -> %File {
pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) %File {
if (is_posix) {
const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC;
const fd = try os.posixOpen(path, flags, mode, allocator);
@ -169,7 +170,7 @@ pub const File = struct {
}
pub fn openHandle(handle: os.FileHandle) -> File {
pub fn openHandle(handle: os.FileHandle) File {
return File {
.handle = handle,
};
@ -178,17 +179,17 @@ pub const File = struct {
/// Upon success, the stream is in an uninitialized state. To continue using it,
/// you must use the open() function.
pub fn close(self: &File) {
pub fn close(self: &File) void {
os.close(self.handle);
self.handle = undefined;
}
/// Calls `os.isTty` on `self.handle`.
pub fn isTty(self: &File) -> bool {
pub fn isTty(self: &File) bool {
return os.isTty(self.handle);
}
pub fn seekForward(self: &File, amount: isize) -> %void {
pub fn seekForward(self: &File, amount: isize) %void {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const result = system.lseek(self.handle, amount, system.SEEK_CUR);
@ -204,14 +205,24 @@ pub const File = struct {
};
}
},
Os.windows => {
if (system.SetFilePointerEx(self.handle, amount, null, system.FILE_CURRENT) == 0) {
const err = system.GetLastError();
return switch (err) {
system.ERROR.INVALID_PARAMETER => error.BadFd,
else => os.unexpectedErrorWindows(err),
};
}
},
else => @compileError("unsupported OS"),
}
}
pub fn seekTo(self: &File, pos: usize) -> %void {
pub fn seekTo(self: &File, pos: usize) %void {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const result = system.lseek(self.handle, @bitCast(isize, pos), system.SEEK_SET);
const ipos = try math.cast(isize, pos);
const result = system.lseek(self.handle, ipos, system.SEEK_SET);
const err = system.getErrno(result);
if (err > 0) {
return switch (err) {
@ -224,11 +235,21 @@ pub const File = struct {
};
}
},
Os.windows => {
const ipos = try math.cast(isize, pos);
if (system.SetFilePointerEx(self.handle, ipos, null, system.FILE_BEGIN) == 0) {
const err = system.GetLastError();
return switch (err) {
system.ERROR.INVALID_PARAMETER => error.BadFd,
else => os.unexpectedErrorWindows(err),
};
}
},
else => @compileError("unsupported OS: " ++ @tagName(builtin.os)),
}
}
pub fn getPos(self: &File) -> %usize {
pub fn getPos(self: &File) %usize {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const result = system.lseek(self.handle, 0, system.SEEK_CUR);
@ -245,11 +266,30 @@ pub const File = struct {
}
return result;
},
Os.windows => {
var pos : system.LARGE_INTEGER = undefined;
if (system.SetFilePointerEx(self.handle, 0, &pos, system.FILE_CURRENT) == 0) {
const err = system.GetLastError();
return switch (err) {
system.ERROR.INVALID_PARAMETER => error.BadFd,
else => os.unexpectedErrorWindows(err),
};
}
assert(pos >= 0);
if (@sizeOf(@typeOf(pos)) > @sizeOf(usize)) {
if (pos > @maxValue(usize)) {
return error.FilePosLargerThanPointerRange;
}
}
return usize(pos);
},
else => @compileError("unsupported OS"),
}
}
pub fn getEndPos(self: &File) -> %usize {
pub fn getEndPos(self: &File) %usize {
if (is_posix) {
var stat: system.Stat = undefined;
const err = system.getErrno(system.fstat(self.handle, &stat));
@ -278,7 +318,7 @@ pub const File = struct {
}
}
pub fn read(self: &File, buffer: []u8) -> %usize {
pub fn read(self: &File, buffer: []u8) %usize {
if (is_posix) {
var index: usize = 0;
while (index < buffer.len) {
@ -320,7 +360,7 @@ pub const File = struct {
}
}
fn write(self: &File, bytes: []const u8) -> %void {
fn write(self: &File, bytes: []const u8) %void {
if (is_posix) {
try os.posixWrite(self.handle, bytes);
} else if (is_windows) {
@ -338,12 +378,12 @@ pub const InStream = struct {
/// Return the number of bytes read. If the number read is smaller than buf.len, it
/// means the stream reached the end. Reaching the end of a stream is not an error
/// condition.
readFn: fn(self: &InStream, buffer: []u8) -> %usize,
readFn: fn(self: &InStream, buffer: []u8) %usize,
/// Replaces `buffer` contents by reading from the stream until it is finished.
/// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and
/// the contents read from the stream are lost.
pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) -> %void {
pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) %void {
try buffer.resize(0);
var actual_buf_len: usize = 0;
@ -368,7 +408,7 @@ pub const InStream = struct {
/// memory would be greater than `max_size`, returns `error.StreamTooLong`.
/// Caller owns returned memory.
/// If this function returns an error, the contents from the stream read so far are lost.
pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) -> %[]u8 {
pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) %[]u8 {
var buf = Buffer.initNull(allocator);
defer buf.deinit();
@ -380,7 +420,7 @@ pub const InStream = struct {
/// Does not include the delimiter in the result.
/// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents
/// read from the stream so far are lost.
pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) -> %void {
pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) %void {
try buf.resize(0);
while (true) {
@ -403,7 +443,7 @@ pub const InStream = struct {
/// Caller owns returned memory.
/// If this function returns an error, the contents from the stream read so far are lost.
pub fn readUntilDelimiterAlloc(self: &InStream, allocator: &mem.Allocator,
delimiter: u8, max_size: usize) -> %[]u8
delimiter: u8, max_size: usize) %[]u8
{
var buf = Buffer.initNull(allocator);
defer buf.deinit();
@ -415,43 +455,43 @@ pub const InStream = struct {
/// Returns the number of bytes read. If the number read is smaller than buf.len, it
/// means the stream reached the end. Reaching the end of a stream is not an error
/// condition.
pub fn read(self: &InStream, buffer: []u8) -> %usize {
pub fn read(self: &InStream, buffer: []u8) %usize {
return self.readFn(self, buffer);
}
/// Same as `read` but end of stream returns `error.EndOfStream`.
pub fn readNoEof(self: &InStream, buf: []u8) -> %void {
pub fn readNoEof(self: &InStream, buf: []u8) %void {
const amt_read = try self.read(buf);
if (amt_read < buf.len) return error.EndOfStream;
}
/// Reads 1 byte from the stream or returns `error.EndOfStream`.
pub fn readByte(self: &InStream) -> %u8 {
pub fn readByte(self: &InStream) %u8 {
var result: [1]u8 = undefined;
try self.readNoEof(result[0..]);
return result[0];
}
/// Same as `readByte` except the returned byte is signed.
pub fn readByteSigned(self: &InStream) -> %i8 {
pub fn readByteSigned(self: &InStream) %i8 {
return @bitCast(i8, try self.readByte());
}
pub fn readIntLe(self: &InStream, comptime T: type) -> %T {
pub fn readIntLe(self: &InStream, comptime T: type) %T {
return self.readInt(builtin.Endian.Little, T);
}
pub fn readIntBe(self: &InStream, comptime T: type) -> %T {
pub fn readIntBe(self: &InStream, comptime T: type) %T {
return self.readInt(builtin.Endian.Big, T);
}
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T {
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) %T {
var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]);
return mem.readInt(bytes, T, endian);
}
pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) -> %T {
pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) %T {
assert(size <= @sizeOf(T));
assert(size <= 8);
var input_buf: [8]u8 = undefined;
@ -464,22 +504,22 @@ pub const InStream = struct {
};
pub const OutStream = struct {
writeFn: fn(self: &OutStream, bytes: []const u8) -> %void,
writeFn: fn(self: &OutStream, bytes: []const u8) %void,
pub fn print(self: &OutStream, comptime format: []const u8, args: ...) -> %void {
pub fn print(self: &OutStream, comptime format: []const u8, args: ...) %void {
return std.fmt.format(self, self.writeFn, format, args);
}
pub fn write(self: &OutStream, bytes: []const u8) -> %void {
pub fn write(self: &OutStream, bytes: []const u8) %void {
return self.writeFn(self, bytes);
}
pub fn writeByte(self: &OutStream, byte: u8) -> %void {
pub fn writeByte(self: &OutStream, byte: u8) %void {
const slice = (&byte)[0..1];
return self.writeFn(self, slice);
}
pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) -> %void {
pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) %void {
const slice = (&byte)[0..1];
var i: usize = 0;
while (i < n) : (i += 1) {
@ -492,25 +532,25 @@ pub const OutStream = struct {
/// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed
/// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned.
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) -> %void {
pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) %void {
var file = try File.openWrite(path, allocator);
defer file.close();
try file.write(data);
}
/// On success, caller owns returned buffer.
pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 {
pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) %[]u8 {
return readFileAllocExtra(path, allocator, 0);
}
/// On success, caller owns returned buffer.
/// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized.
pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 {
pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) %[]u8 {
var file = try File.openRead(path, allocator);
defer file.close();
const size = try file.getEndPos();
const buf = try allocator.alloc(u8, size + extra_len);
%defer allocator.free(buf);
errdefer allocator.free(buf);
var adapter = FileInStream.init(&file);
try adapter.stream.readNoEof(buf[0..size]);
@ -519,7 +559,7 @@ pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len
pub const BufferedInStream = BufferedInStreamCustom(os.page_size);
pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
pub fn BufferedInStreamCustom(comptime buffer_size: usize) type {
return struct {
const Self = this;
@ -531,7 +571,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
start_index: usize,
end_index: usize,
pub fn init(unbuffered_in_stream: &InStream) -> Self {
pub fn init(unbuffered_in_stream: &InStream) Self {
return Self {
.unbuffered_in_stream = unbuffered_in_stream,
.buffer = undefined,
@ -549,7 +589,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
};
}
fn readFn(in_stream: &InStream, dest: []u8) -> %usize {
fn readFn(in_stream: &InStream, dest: []u8) %usize {
const self = @fieldParentPtr(Self, "stream", in_stream);
var dest_index: usize = 0;
@ -590,7 +630,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
pub const BufferedOutStream = BufferedOutStreamCustom(os.page_size);
pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
return struct {
const Self = this;
@ -601,7 +641,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
buffer: [buffer_size]u8,
index: usize,
pub fn init(unbuffered_out_stream: &OutStream) -> Self {
pub fn init(unbuffered_out_stream: &OutStream) Self {
return Self {
.unbuffered_out_stream = unbuffered_out_stream,
.buffer = undefined,
@ -612,7 +652,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
};
}
pub fn flush(self: &Self) -> %void {
pub fn flush(self: &Self) %void {
if (self.index == 0)
return;
@ -620,7 +660,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
self.index = 0;
}
fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
const self = @fieldParentPtr(Self, "stream", out_stream);
if (bytes.len >= self.buffer.len) {
@ -649,7 +689,7 @@ pub const BufferOutStream = struct {
buffer: &Buffer,
stream: OutStream,
pub fn init(buffer: &Buffer) -> BufferOutStream {
pub fn init(buffer: &Buffer) BufferOutStream {
return BufferOutStream {
.buffer = buffer,
.stream = OutStream {
@ -658,7 +698,7 @@ pub const BufferOutStream = struct {
};
}
fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
const self = @fieldParentPtr(BufferOutStream, "stream", out_stream);
return self.buffer.append(bytes);
}

View File

@ -5,17 +5,17 @@ const mem = std.mem;
const Allocator = mem.Allocator;
/// Generic non-intrusive doubly linked list.
pub fn LinkedList(comptime T: type) -> type {
pub fn LinkedList(comptime T: type) type {
return BaseLinkedList(T, void, "");
}
/// Generic intrusive doubly linked list.
pub fn IntrusiveLinkedList(comptime ParentType: type, comptime field_name: []const u8) -> type {
pub fn IntrusiveLinkedList(comptime ParentType: type, comptime field_name: []const u8) type {
return BaseLinkedList(void, ParentType, field_name);
}
/// Generic doubly linked list.
fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_name: []const u8) -> type {
fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_name: []const u8) type {
return struct {
const Self = this;
@ -25,7 +25,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
next: ?&Node,
data: T,
pub fn init(value: &const T) -> Node {
pub fn init(value: &const T) Node {
return Node {
.prev = null,
.next = null,
@ -33,12 +33,12 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
};
}
pub fn initIntrusive() -> Node {
pub fn initIntrusive() Node {
// TODO: when #678 is solved this can become `init`.
return Node.init({});
}
pub fn toData(node: &Node) -> &ParentType {
pub fn toData(node: &Node) &ParentType {
comptime assert(isIntrusive());
return @fieldParentPtr(ParentType, field_name, node);
}
@ -52,7 +52,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// An empty linked list.
pub fn init() -> Self {
pub fn init() Self {
return Self {
.first = null,
.last = null,
@ -60,7 +60,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
};
}
fn isIntrusive() -> bool {
fn isIntrusive() bool {
return ParentType != void or field_name.len != 0;
}
@ -69,7 +69,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
/// Arguments:
/// node: Pointer to a node in the list.
/// new_node: Pointer to the new node to insert.
pub fn insertAfter(list: &Self, node: &Node, new_node: &Node) {
pub fn insertAfter(list: &Self, node: &Node, new_node: &Node) void {
new_node.prev = node;
if (node.next) |next_node| {
// Intermediate node.
@ -90,7 +90,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
/// Arguments:
/// node: Pointer to a node in the list.
/// new_node: Pointer to the new node to insert.
pub fn insertBefore(list: &Self, node: &Node, new_node: &Node) {
pub fn insertBefore(list: &Self, node: &Node, new_node: &Node) void {
new_node.next = node;
if (node.prev) |prev_node| {
// Intermediate node.
@ -110,7 +110,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Arguments:
/// new_node: Pointer to the new node to insert.
pub fn append(list: &Self, new_node: &Node) {
pub fn append(list: &Self, new_node: &Node) void {
if (list.last) |last| {
// Insert after last.
list.insertAfter(last, new_node);
@ -124,7 +124,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Arguments:
/// new_node: Pointer to the new node to insert.
pub fn prepend(list: &Self, new_node: &Node) {
pub fn prepend(list: &Self, new_node: &Node) void {
if (list.first) |first| {
// Insert before first.
list.insertBefore(first, new_node);
@ -143,7 +143,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Arguments:
/// node: Pointer to the node to be removed.
pub fn remove(list: &Self, node: &Node) {
pub fn remove(list: &Self, node: &Node) void {
if (node.prev) |prev_node| {
// Intermediate node.
prev_node.next = node.next;
@ -167,7 +167,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// A pointer to the last node in the list.
pub fn pop(list: &Self) -> ?&Node {
pub fn pop(list: &Self) ?&Node {
const last = list.last ?? return null;
list.remove(last);
return last;
@ -177,7 +177,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// A pointer to the first node in the list.
pub fn popFirst(list: &Self) -> ?&Node {
pub fn popFirst(list: &Self) ?&Node {
const first = list.first ?? return null;
list.remove(first);
return first;
@ -190,7 +190,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// A pointer to the new node.
pub fn allocateNode(list: &Self, allocator: &Allocator) -> %&Node {
pub fn allocateNode(list: &Self, allocator: &Allocator) %&Node {
comptime assert(!isIntrusive());
return allocator.create(Node);
}
@ -200,7 +200,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
/// Arguments:
/// node: Pointer to the node to deallocate.
/// allocator: Dynamic memory allocator.
pub fn destroyNode(list: &Self, node: &Node, allocator: &Allocator) {
pub fn destroyNode(list: &Self, node: &Node, allocator: &Allocator) void {
comptime assert(!isIntrusive());
allocator.destroy(node);
}
@ -213,7 +213,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// A pointer to the new node.
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node {
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) %&Node {
comptime assert(!isIntrusive());
var node = try list.allocateNode(allocator);
*node = Node.init(data);

View File

@ -6,7 +6,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn acos(x: var) -> @typeOf(x) {
pub fn acos(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => acos32(x),
@ -15,7 +15,7 @@ pub fn acos(x: var) -> @typeOf(x) {
};
}
fn r32(z: f32) -> f32 {
fn r32(z: f32) f32 {
const pS0 = 1.6666586697e-01;
const pS1 = -4.2743422091e-02;
const pS2 = -8.6563630030e-03;
@ -26,7 +26,7 @@ fn r32(z: f32) -> f32 {
return p / q;
}
fn acos32(x: f32) -> f32 {
fn acos32(x: f32) f32 {
const pio2_hi = 1.5707962513e+00;
const pio2_lo = 7.5497894159e-08;
@ -73,7 +73,7 @@ fn acos32(x: f32) -> f32 {
return 2 * (df + w);
}
fn r64(z: f64) -> f64 {
fn r64(z: f64) f64 {
const pS0: f64 = 1.66666666666666657415e-01;
const pS1: f64 = -3.25565818622400915405e-01;
const pS2: f64 = 2.01212532134862925881e-01;
@ -90,7 +90,7 @@ fn r64(z: f64) -> f64 {
return p / q;
}
fn acos64(x: f64) -> f64 {
fn acos64(x: f64) f64 {
const pio2_hi: f64 = 1.57079632679489655800e+00;
const pio2_lo: f64 = 6.12323399573676603587e-17;

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn acosh(x: var) -> @typeOf(x) {
pub fn acosh(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => acosh32(x),
@ -18,7 +18,7 @@ pub fn acosh(x: var) -> @typeOf(x) {
}
// acosh(x) = log(x + sqrt(x * x - 1))
fn acosh32(x: f32) -> f32 {
fn acosh32(x: f32) f32 {
const u = @bitCast(u32, x);
const i = u & 0x7FFFFFFF;
@ -36,7 +36,7 @@ fn acosh32(x: f32) -> f32 {
}
}
fn acosh64(x: f64) -> f64 {
fn acosh64(x: f64) f64 {
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;

View File

@ -7,7 +7,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn asin(x: var) -> @typeOf(x) {
pub fn asin(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => asin32(x),
@ -16,7 +16,7 @@ pub fn asin(x: var) -> @typeOf(x) {
};
}
fn r32(z: f32) -> f32 {
fn r32(z: f32) f32 {
const pS0 = 1.6666586697e-01;
const pS1 = -4.2743422091e-02;
const pS2 = -8.6563630030e-03;
@ -27,7 +27,7 @@ fn r32(z: f32) -> f32 {
return p / q;
}
fn asin32(x: f32) -> f32 {
fn asin32(x: f32) f32 {
const pio2 = 1.570796326794896558e+00;
const hx: u32 = @bitCast(u32, x);
@ -65,7 +65,7 @@ fn asin32(x: f32) -> f32 {
}
}
fn r64(z: f64) -> f64 {
fn r64(z: f64) f64 {
const pS0: f64 = 1.66666666666666657415e-01;
const pS1: f64 = -3.25565818622400915405e-01;
const pS2: f64 = 2.01212532134862925881e-01;
@ -82,7 +82,7 @@ fn r64(z: f64) -> f64 {
return p / q;
}
fn asin64(x: f64) -> f64 {
fn asin64(x: f64) f64 {
const pio2_hi: f64 = 1.57079632679489655800e+00;
const pio2_lo: f64 = 6.12323399573676603587e-17;

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn asinh(x: var) -> @typeOf(x) {
pub fn asinh(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => asinh32(x),
@ -18,7 +18,7 @@ pub fn asinh(x: var) -> @typeOf(x) {
}
// asinh(x) = sign(x) * log(|x| + sqrt(x * x + 1)) ~= x - x^3/6 + o(x^5)
fn asinh32(x: f32) -> f32 {
fn asinh32(x: f32) f32 {
const u = @bitCast(u32, x);
const i = u & 0x7FFFFFFF;
const s = i >> 31;
@ -50,7 +50,7 @@ fn asinh32(x: f32) -> f32 {
return if (s != 0) -rx else rx;
}
fn asinh64(x: f64) -> f64 {
fn asinh64(x: f64) f64 {
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
const s = u >> 63;

View File

@ -7,7 +7,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn atan(x: var) -> @typeOf(x) {
pub fn atan(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => atan32(x),
@ -16,7 +16,7 @@ pub fn atan(x: var) -> @typeOf(x) {
};
}
fn atan32(x_: f32) -> f32 {
fn atan32(x_: f32) f32 {
const atanhi = []const f32 {
4.6364760399e-01, // atan(0.5)hi
7.8539812565e-01, // atan(1.0)hi
@ -108,7 +108,7 @@ fn atan32(x_: f32) -> f32 {
}
}
fn atan64(x_: f64) -> f64 {
fn atan64(x_: f64) f64 {
const atanhi = []const f64 {
4.63647609000806093515e-01, // atan(0.5)hi
7.85398163397448278999e-01, // atan(1.0)hi

View File

@ -22,7 +22,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
fn atan2(comptime T: type, x: T, y: T) -> T {
fn atan2(comptime T: type, x: T, y: T) T {
return switch (T) {
f32 => atan2_32(x, y),
f64 => atan2_64(x, y),
@ -30,7 +30,7 @@ fn atan2(comptime T: type, x: T, y: T) -> T {
};
}
fn atan2_32(y: f32, x: f32) -> f32 {
fn atan2_32(y: f32, x: f32) f32 {
const pi: f32 = 3.1415927410e+00;
const pi_lo: f32 = -8.7422776573e-08;
@ -115,7 +115,7 @@ fn atan2_32(y: f32, x: f32) -> f32 {
}
}
fn atan2_64(y: f64, x: f64) -> f64 {
fn atan2_64(y: f64, x: f64) f64 {
const pi: f64 = 3.1415926535897931160E+00;
const pi_lo: f64 = 1.2246467991473531772E-16;

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn atanh(x: var) -> @typeOf(x) {
pub fn atanh(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => atanh_32(x),
@ -18,7 +18,7 @@ pub fn atanh(x: var) -> @typeOf(x) {
}
// atanh(x) = log((1 + x) / (1 - x)) / 2 = log1p(2x / (1 - x)) / 2 ~= x + x^3 / 3 + o(x^5)
fn atanh_32(x: f32) -> f32 {
fn atanh_32(x: f32) f32 {
const u = @bitCast(u32, x);
const i = u & 0x7FFFFFFF;
const s = u >> 31;
@ -47,7 +47,7 @@ fn atanh_32(x: f32) -> f32 {
return if (s != 0) -y else y;
}
fn atanh_64(x: f64) -> f64 {
fn atanh_64(x: f64) f64 {
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
const s = u >> 63;

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn cbrt(x: var) -> @typeOf(x) {
pub fn cbrt(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => cbrt32(x),
@ -17,7 +17,7 @@ pub fn cbrt(x: var) -> @typeOf(x) {
};
}
fn cbrt32(x: f32) -> f32 {
fn cbrt32(x: f32) f32 {
const B1: u32 = 709958130; // (127 - 127.0 / 3 - 0.03306235651) * 2^23
const B2: u32 = 642849266; // (127 - 127.0 / 3 - 24 / 3 - 0.03306235651) * 2^23
@ -57,7 +57,7 @@ fn cbrt32(x: f32) -> f32 {
return f32(t);
}
fn cbrt64(x: f64) -> f64 {
fn cbrt64(x: f64) f64 {
const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^20
const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^20

View File

@ -9,7 +9,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn ceil(x: var) -> @typeOf(x) {
pub fn ceil(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => ceil32(x),
@ -18,7 +18,7 @@ pub fn ceil(x: var) -> @typeOf(x) {
};
}
fn ceil32(x: f32) -> f32 {
fn ceil32(x: f32) f32 {
var u = @bitCast(u32, x);
var e = i32((u >> 23) & 0xFF) - 0x7F;
var m: u32 = undefined;
@ -51,7 +51,7 @@ fn ceil32(x: f32) -> f32 {
}
}
fn ceil64(x: f64) -> f64 {
fn ceil64(x: f64) f64 {
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
var y: f64 = undefined;

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn copysign(comptime T: type, x: T, y: T) -> T {
pub fn copysign(comptime T: type, x: T, y: T) T {
return switch (T) {
f32 => copysign32(x, y),
f64 => copysign64(x, y),
@ -10,7 +10,7 @@ pub fn copysign(comptime T: type, x: T, y: T) -> T {
};
}
fn copysign32(x: f32, y: f32) -> f32 {
fn copysign32(x: f32, y: f32) f32 {
const ux = @bitCast(u32, x);
const uy = @bitCast(u32, y);
@ -19,7 +19,7 @@ fn copysign32(x: f32, y: f32) -> f32 {
return @bitCast(f32, h1 | h2);
}
fn copysign64(x: f64, y: f64) -> f64 {
fn copysign64(x: f64, y: f64) f64 {
const ux = @bitCast(u64, x);
const uy = @bitCast(u64, y);

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn cos(x: var) -> @typeOf(x) {
pub fn cos(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => cos32(x),
@ -36,7 +36,7 @@ const C5 = 4.16666666666665929218E-2;
// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
//
// This may have slight differences on some edge cases and may need to replaced if so.
fn cos32(x_: f32) -> f32 {
fn cos32(x_: f32) f32 {
@setFloatMode(this, @import("builtin").FloatMode.Strict);
const pi4a = 7.85398125648498535156e-1;
@ -89,7 +89,7 @@ fn cos32(x_: f32) -> f32 {
}
}
fn cos64(x_: f64) -> f64 {
fn cos64(x_: f64) f64 {
const pi4a = 7.85398125648498535156e-1;
const pi4b = 3.77489470793079817668E-8;
const pi4c = 2.69515142907905952645E-15;

View File

@ -10,7 +10,7 @@ const math = std.math;
const expo2 = @import("expo2.zig").expo2;
const assert = std.debug.assert;
pub fn cosh(x: var) -> @typeOf(x) {
pub fn cosh(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => cosh32(x),
@ -22,7 +22,7 @@ pub fn cosh(x: var) -> @typeOf(x) {
// cosh(x) = (exp(x) + 1 / exp(x)) / 2
// = 1 + 0.5 * (exp(x) - 1) * (exp(x) - 1) / exp(x)
// = 1 + (x * x) / 2 + o(x^4)
fn cosh32(x: f32) -> f32 {
fn cosh32(x: f32) f32 {
const u = @bitCast(u32, x);
const ux = u & 0x7FFFFFFF;
const ax = @bitCast(f32, ux);
@ -47,7 +47,7 @@ fn cosh32(x: f32) -> f32 {
return expo2(ax);
}
fn cosh64(x: f64) -> f64 {
fn cosh64(x: f64) f64 {
const u = @bitCast(u64, x);
const w = u32(u >> 32);
const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));

View File

@ -7,7 +7,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn exp(x: var) -> @typeOf(x) {
pub fn exp(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => exp32(x),
@ -16,7 +16,7 @@ pub fn exp(x: var) -> @typeOf(x) {
};
}
fn exp32(x_: f32) -> f32 {
fn exp32(x_: f32) f32 {
const half = []f32 { 0.5, -0.5 };
const ln2hi = 6.9314575195e-1;
const ln2lo = 1.4286067653e-6;
@ -93,7 +93,7 @@ fn exp32(x_: f32) -> f32 {
}
}
fn exp64(x_: f64) -> f64 {
fn exp64(x_: f64) f64 {
const half = []const f64 { 0.5, -0.5 };
const ln2hi: f64 = 6.93147180369123816490e-01;
const ln2lo: f64 = 1.90821492927058770002e-10;

View File

@ -7,7 +7,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn exp2(x: var) -> @typeOf(x) {
pub fn exp2(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => exp2_32(x),
@ -35,7 +35,7 @@ const exp2ft = []const f64 {
0x1.5ab07dd485429p+0,
};
fn exp2_32(x: f32) -> f32 {
fn exp2_32(x: f32) f32 {
@setFloatMode(this, @import("builtin").FloatMode.Strict);
const tblsiz = u32(exp2ft.len);
@ -352,7 +352,7 @@ const exp2dt = []f64 {
0x1.690f4b19e9471p+0, -0x1.9780p-45,
};
fn exp2_64(x: f64) -> f64 {
fn exp2_64(x: f64) f64 {
@setFloatMode(this, @import("builtin").FloatMode.Strict);
const tblsiz = u32(exp2dt.len / 2);

View File

@ -9,7 +9,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn expm1(x: var) -> @typeOf(x) {
pub fn expm1(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => expm1_32(x),
@ -18,7 +18,7 @@ pub fn expm1(x: var) -> @typeOf(x) {
};
}
fn expm1_32(x_: f32) -> f32 {
fn expm1_32(x_: f32) f32 {
@setFloatMode(this, builtin.FloatMode.Strict);
const o_threshold: f32 = 8.8721679688e+01;
const ln2_hi: f32 = 6.9313812256e-01;
@ -145,7 +145,7 @@ fn expm1_32(x_: f32) -> f32 {
}
}
fn expm1_64(x_: f64) -> f64 {
fn expm1_64(x_: f64) f64 {
@setFloatMode(this, builtin.FloatMode.Strict);
const o_threshold: f64 = 7.09782712893383973096e+02;
const ln2_hi: f64 = 6.93147180369123816490e-01;

View File

@ -1,6 +1,6 @@
const math = @import("index.zig");
pub fn expo2(x: var) -> @typeOf(x) {
pub fn expo2(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => expo2f(x),
@ -9,7 +9,7 @@ pub fn expo2(x: var) -> @typeOf(x) {
};
}
fn expo2f(x: f32) -> f32 {
fn expo2f(x: f32) f32 {
const k: u32 = 235;
const kln2 = 0x1.45C778p+7;
@ -18,7 +18,7 @@ fn expo2f(x: f32) -> f32 {
return math.exp(x - kln2) * scale * scale;
}
fn expo2d(x: f64) -> f64 {
fn expo2d(x: f64) f64 {
const k: u32 = 2043;
const kln2 = 0x1.62066151ADD8BP+10;

View File

@ -7,7 +7,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn fabs(x: var) -> @typeOf(x) {
pub fn fabs(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => fabs32(x),
@ -16,13 +16,13 @@ pub fn fabs(x: var) -> @typeOf(x) {
};
}
fn fabs32(x: f32) -> f32 {
fn fabs32(x: f32) f32 {
var u = @bitCast(u32, x);
u &= 0x7FFFFFFF;
return @bitCast(f32, u);
}
fn fabs64(x: f64) -> f64 {
fn fabs64(x: f64) f64 {
var u = @bitCast(u64, x);
u &= @maxValue(u64) >> 1;
return @bitCast(f64, u);

View File

@ -9,7 +9,7 @@ const assert = std.debug.assert;
const std = @import("../index.zig");
const math = std.math;
pub fn floor(x: var) -> @typeOf(x) {
pub fn floor(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => floor32(x),
@ -18,7 +18,7 @@ pub fn floor(x: var) -> @typeOf(x) {
};
}
fn floor32(x: f32) -> f32 {
fn floor32(x: f32) f32 {
var u = @bitCast(u32, x);
const e = i32((u >> 23) & 0xFF) - 0x7F;
var m: u32 = undefined;
@ -52,7 +52,7 @@ fn floor32(x: f32) -> f32 {
}
}
fn floor64(x: f64) -> f64 {
fn floor64(x: f64) f64 {
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
var y: f64 = undefined;

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {
pub fn fma(comptime T: type, x: T, y: T, z: T) T {
return switch (T) {
f32 => fma32(x, y, z),
f64 => fma64(x, y ,z),
@ -10,7 +10,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {
};
}
fn fma32(x: f32, y: f32, z: f32) -> f32 {
fn fma32(x: f32, y: f32, z: f32) f32 {
const xy = f64(x) * y;
const xy_z = xy + z;
const u = @bitCast(u64, xy_z);
@ -24,7 +24,7 @@ fn fma32(x: f32, y: f32, z: f32) -> f32 {
}
}
fn fma64(x: f64, y: f64, z: f64) -> f64 {
fn fma64(x: f64, y: f64, z: f64) f64 {
if (!math.isFinite(x) or !math.isFinite(y)) {
return x * y + z;
}
@ -73,7 +73,7 @@ fn fma64(x: f64, y: f64, z: f64) -> f64 {
const dd = struct { hi: f64, lo: f64, };
fn dd_add(a: f64, b: f64) -> dd {
fn dd_add(a: f64, b: f64) dd {
var ret: dd = undefined;
ret.hi = a + b;
const s = ret.hi - a;
@ -81,7 +81,7 @@ fn dd_add(a: f64, b: f64) -> dd {
return ret;
}
fn dd_mul(a: f64, b: f64) -> dd {
fn dd_mul(a: f64, b: f64) dd {
var ret: dd = undefined;
const split: f64 = 0x1.0p27 + 1.0;
@ -103,7 +103,7 @@ fn dd_mul(a: f64, b: f64) -> dd {
return ret;
}
fn add_adjusted(a: f64, b: f64) -> f64 {
fn add_adjusted(a: f64, b: f64) f64 {
var sum = dd_add(a, b);
if (sum.lo != 0) {
var uhii = @bitCast(u64, sum.hi);
@ -117,7 +117,7 @@ fn add_adjusted(a: f64, b: f64) -> f64 {
return sum.hi;
}
fn add_and_denorm(a: f64, b: f64, scale: i32) -> f64 {
fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
var sum = dd_add(a, b);
if (sum.lo != 0) {
var uhii = @bitCast(u64, sum.hi);

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
fn frexp_result(comptime T: type) -> type {
fn frexp_result(comptime T: type) type {
return struct {
significand: T,
exponent: i32,
@ -17,7 +17,7 @@ fn frexp_result(comptime T: type) -> type {
pub const frexp32_result = frexp_result(f32);
pub const frexp64_result = frexp_result(f64);
pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {
pub fn frexp(x: var) frexp_result(@typeOf(x)) {
const T = @typeOf(x);
return switch (T) {
f32 => frexp32(x),
@ -26,7 +26,7 @@ pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {
};
}
fn frexp32(x: f32) -> frexp32_result {
fn frexp32(x: f32) frexp32_result {
var result: frexp32_result = undefined;
var y = @bitCast(u32, x);
@ -63,7 +63,7 @@ fn frexp32(x: f32) -> frexp32_result {
return result;
}
fn frexp64(x: f64) -> frexp64_result {
fn frexp64(x: f64) frexp64_result {
var result: frexp64_result = undefined;
var y = @bitCast(u64, x);

View File

@ -9,7 +9,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn hypot(comptime T: type, x: T, y: T) -> T {
pub fn hypot(comptime T: type, x: T, y: T) T {
return switch (T) {
f32 => hypot32(x, y),
f64 => hypot64(x, y),
@ -17,7 +17,7 @@ pub fn hypot(comptime T: type, x: T, y: T) -> T {
};
}
fn hypot32(x: f32, y: f32) -> f32 {
fn hypot32(x: f32, y: f32) f32 {
var ux = @bitCast(u32, x);
var uy = @bitCast(u32, y);
@ -52,7 +52,7 @@ fn hypot32(x: f32, y: f32) -> f32 {
return z * math.sqrt(f32(f64(x) * x + f64(y) * y));
}
fn sq(hi: &f64, lo: &f64, x: f64) {
fn sq(hi: &f64, lo: &f64, x: f64) void {
const split: f64 = 0x1.0p27 + 1.0;
const xc = x * split;
const xh = x - xc + xc;
@ -61,7 +61,7 @@ fn sq(hi: &f64, lo: &f64, x: f64) {
*lo = xh * xh - *hi + 2 * xh * xl + xl * xl;
}
fn hypot64(x: f64, y: f64) -> f64 {
fn hypot64(x: f64, y: f64) f64 {
var ux = @bitCast(u64, x);
var uy = @bitCast(u64, y);

View File

@ -8,7 +8,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn ilogb(x: var) -> i32 {
pub fn ilogb(x: var) i32 {
const T = @typeOf(x);
return switch (T) {
f32 => ilogb32(x),
@ -21,7 +21,7 @@ pub fn ilogb(x: var) -> i32 {
const fp_ilogbnan = -1 - i32(@maxValue(u32) >> 1);
const fp_ilogb0 = fp_ilogbnan;
fn ilogb32(x: f32) -> i32 {
fn ilogb32(x: f32) i32 {
var u = @bitCast(u32, x);
var e = i32((u >> 23) & 0xFF);
@ -57,7 +57,7 @@ fn ilogb32(x: f32) -> i32 {
return e - 0x7F;
}
fn ilogb64(x: f64) -> i32 {
fn ilogb64(x: f64) i32 {
var u = @bitCast(u64, x);
var e = i32((u >> 52) & 0x7FF);

View File

@ -35,13 +35,13 @@ pub const nan = @import("nan.zig").nan;
pub const snan = @import("nan.zig").snan;
pub const inf = @import("inf.zig").inf;
pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) -> bool {
pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) bool {
assert(@typeId(T) == TypeId.Float);
return fabs(x - y) < epsilon;
}
// TODO: Hide the following in an internal module.
pub fn forceEval(value: var) {
pub fn forceEval(value: var) void {
const T = @typeOf(value);
switch (T) {
f32 => {
@ -60,23 +60,23 @@ pub fn forceEval(value: var) {
}
}
pub fn raiseInvalid() {
pub fn raiseInvalid() void {
// Raise INVALID fpu exception
}
pub fn raiseUnderflow() {
pub fn raiseUnderflow() void {
// Raise UNDERFLOW fpu exception
}
pub fn raiseOverflow() {
pub fn raiseOverflow() void {
// Raise OVERFLOW fpu exception
}
pub fn raiseInexact() {
pub fn raiseInexact() void {
// Raise INEXACT fpu exception
}
pub fn raiseDivByZero() {
pub fn raiseDivByZero() void {
// Raise INEXACT fpu exception
}
@ -175,7 +175,7 @@ test "math" {
}
pub fn min(x: var, y: var) -> @typeOf(x + y) {
pub fn min(x: var, y: var) @typeOf(x + y) {
return if (x < y) x else y;
}
@ -183,7 +183,7 @@ test "math.min" {
assert(min(i32(-1), i32(2)) == -1);
}
pub fn max(x: var, y: var) -> @typeOf(x + y) {
pub fn max(x: var, y: var) @typeOf(x + y) {
return if (x > y) x else y;
}
@ -192,36 +192,36 @@ test "math.max" {
}
error Overflow;
pub fn mul(comptime T: type, a: T, b: T) -> %T {
pub fn mul(comptime T: type, a: T, b: T) %T {
var answer: T = undefined;
return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
error Overflow;
pub fn add(comptime T: type, a: T, b: T) -> %T {
pub fn add(comptime T: type, a: T, b: T) %T {
var answer: T = undefined;
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
error Overflow;
pub fn sub(comptime T: type, a: T, b: T) -> %T {
pub fn sub(comptime T: type, a: T, b: T) %T {
var answer: T = undefined;
return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
pub fn negate(x: var) -> %@typeOf(x) {
pub fn negate(x: var) %@typeOf(x) {
return sub(@typeOf(x), 0, x);
}
error Overflow;
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) -> %T {
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) %T {
var answer: T = undefined;
return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
}
/// Shifts left. Overflowed bits are truncated.
/// A negative shift amount results in a right shift.
pub fn shl(comptime T: type, a: T, shift_amt: var) -> T {
pub fn shl(comptime T: type, a: T, shift_amt: var) T {
const abs_shift_amt = absCast(shift_amt);
const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
@ -245,7 +245,7 @@ test "math.shl" {
/// Shifts right. Overflowed bits are truncated.
/// A negative shift amount results in a lefft shift.
pub fn shr(comptime T: type, a: T, shift_amt: var) -> T {
pub fn shr(comptime T: type, a: T, shift_amt: var) T {
const abs_shift_amt = absCast(shift_amt);
const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
@ -269,7 +269,7 @@ test "math.shr" {
/// Rotates right. Only unsigned values can be rotated.
/// Negative shift values results in shift modulo the bit count.
pub fn rotr(comptime T: type, x: T, r: var) -> T {
pub fn rotr(comptime T: type, x: T, r: var) T {
if (T.is_signed) {
@compileError("cannot rotate signed integer");
} else {
@ -288,7 +288,7 @@ test "math.rotr" {
/// Rotates left. Only unsigned values can be rotated.
/// Negative shift values results in shift modulo the bit count.
pub fn rotl(comptime T: type, x: T, r: var) -> T {
pub fn rotl(comptime T: type, x: T, r: var) T {
if (T.is_signed) {
@compileError("cannot rotate signed integer");
} else {
@ -306,7 +306,7 @@ test "math.rotl" {
}
pub fn Log2Int(comptime T: type) -> type {
pub fn Log2Int(comptime T: type) type {
return @IntType(false, log2(T.bit_count));
}
@ -315,7 +315,7 @@ test "math overflow functions" {
comptime testOverflow();
}
fn testOverflow() {
fn testOverflow() void {
assert((mul(i32, 3, 4) catch unreachable) == 12);
assert((add(i32, 3, 4) catch unreachable) == 7);
assert((sub(i32, 3, 4) catch unreachable) == -1);
@ -324,14 +324,14 @@ fn testOverflow() {
error Overflow;
pub fn absInt(x: var) -> %@typeOf(x) {
pub fn absInt(x: var) %@typeOf(x) {
const T = @typeOf(x);
comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
comptime assert(T.is_signed); // must pass a signed integer to absInt
if (x == @minValue(@typeOf(x)))
return error.Overflow;
{
@setDebugSafety(this, false);
@setRuntimeSafety(false);
return if (x < 0) -x else x;
}
}
@ -340,7 +340,7 @@ test "math.absInt" {
testAbsInt();
comptime testAbsInt();
}
fn testAbsInt() {
fn testAbsInt() void {
assert((absInt(i32(-10)) catch unreachable) == 10);
assert((absInt(i32(10)) catch unreachable) == 10);
}
@ -349,8 +349,8 @@ pub const absFloat = @import("fabs.zig").fabs;
error DivisionByZero;
error Overflow;
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {
@setDebugSafety(this, false);
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) %T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
@ -362,7 +362,7 @@ test "math.divTrunc" {
testDivTrunc();
comptime testDivTrunc();
}
fn testDivTrunc() {
fn testDivTrunc() void {
assert((divTrunc(i32, 5, 3) catch unreachable) == 1);
assert((divTrunc(i32, -5, 3) catch unreachable) == -1);
if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
@ -374,8 +374,8 @@ fn testDivTrunc() {
error DivisionByZero;
error Overflow;
pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {
@setDebugSafety(this, false);
pub fn divFloor(comptime T: type, numerator: T, denominator: T) %T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
@ -387,7 +387,7 @@ test "math.divFloor" {
testDivFloor();
comptime testDivFloor();
}
fn testDivFloor() {
fn testDivFloor() void {
assert((divFloor(i32, 5, 3) catch unreachable) == 1);
assert((divFloor(i32, -5, 3) catch unreachable) == -2);
if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
@ -400,8 +400,8 @@ fn testDivFloor() {
error DivisionByZero;
error Overflow;
error UnexpectedRemainder;
pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {
@setDebugSafety(this, false);
pub fn divExact(comptime T: type, numerator: T, denominator: T) %T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
@ -416,7 +416,7 @@ test "math.divExact" {
testDivExact();
comptime testDivExact();
}
fn testDivExact() {
fn testDivExact() void {
assert((divExact(i32, 10, 5) catch unreachable) == 2);
assert((divExact(i32, -10, 5) catch unreachable) == -2);
if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
@ -430,8 +430,8 @@ fn testDivExact() {
error DivisionByZero;
error NegativeDenominator;
pub fn mod(comptime T: type, numerator: T, denominator: T) -> %T {
@setDebugSafety(this, false);
pub fn mod(comptime T: type, numerator: T, denominator: T) %T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
if (denominator < 0)
@ -443,7 +443,7 @@ test "math.mod" {
testMod();
comptime testMod();
}
fn testMod() {
fn testMod() void {
assert((mod(i32, -5, 3) catch unreachable) == 1);
assert((mod(i32, 5, 3) catch unreachable) == 2);
if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
@ -457,8 +457,8 @@ fn testMod() {
error DivisionByZero;
error NegativeDenominator;
pub fn rem(comptime T: type, numerator: T, denominator: T) -> %T {
@setDebugSafety(this, false);
pub fn rem(comptime T: type, numerator: T, denominator: T) %T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
if (denominator < 0)
@ -470,7 +470,7 @@ test "math.rem" {
testRem();
comptime testRem();
}
fn testRem() {
fn testRem() void {
assert((rem(i32, -5, 3) catch unreachable) == -2);
assert((rem(i32, 5, 3) catch unreachable) == 2);
if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
@ -484,7 +484,7 @@ fn testRem() {
/// Returns the absolute value of the integer parameter.
/// Result is an unsigned integer.
pub fn absCast(x: var) -> @IntType(false, @typeOf(x).bit_count) {
pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {
const uint = @IntType(false, @typeOf(x).bit_count);
if (x >= 0)
return uint(x);
@ -506,7 +506,7 @@ test "math.absCast" {
/// Returns the negation of the integer parameter.
/// Result is a signed integer.
error Overflow;
pub fn negateCast(x: var) -> %@IntType(true, @typeOf(x).bit_count) {
pub fn negateCast(x: var) %@IntType(true, @typeOf(x).bit_count) {
if (@typeOf(x).is_signed)
return negate(x);
@ -533,7 +533,7 @@ test "math.negateCast" {
/// Cast an integer to a different integer type. If the value doesn't fit,
/// return an error.
error Overflow;
pub fn cast(comptime T: type, x: var) -> %T {
pub fn cast(comptime T: type, x: var) %T {
comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
if (x > @maxValue(T)) {
return error.Overflow;
@ -542,7 +542,7 @@ pub fn cast(comptime T: type, x: var) -> %T {
}
}
pub fn floorPowerOfTwo(comptime T: type, value: T) -> T {
pub fn floorPowerOfTwo(comptime T: type, value: T) T {
var x = value;
comptime var i = 1;
@ -558,7 +558,7 @@ test "math.floorPowerOfTwo" {
comptime testFloorPowerOfTwo();
}
fn testFloorPowerOfTwo() {
fn testFloorPowerOfTwo() void {
assert(floorPowerOfTwo(u32, 63) == 32);
assert(floorPowerOfTwo(u32, 64) == 64);
assert(floorPowerOfTwo(u32, 65) == 64);

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn inf(comptime T: type) -> T {
pub fn inf(comptime T: type) T {
return switch (T) {
f32 => @bitCast(f32, math.inf_u32),
f64 => @bitCast(f64, math.inf_u64),

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn isFinite(x: var) -> bool {
pub fn isFinite(x: var) bool {
const T = @typeOf(x);
switch (T) {
f32 => {

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn isInf(x: var) -> bool {
pub fn isInf(x: var) bool {
const T = @typeOf(x);
switch (T) {
f32 => {
@ -19,7 +19,7 @@ pub fn isInf(x: var) -> bool {
}
}
pub fn isPositiveInf(x: var) -> bool {
pub fn isPositiveInf(x: var) bool {
const T = @typeOf(x);
switch (T) {
f32 => {
@ -34,7 +34,7 @@ pub fn isPositiveInf(x: var) -> bool {
}
}
pub fn isNegativeInf(x: var) -> bool {
pub fn isNegativeInf(x: var) bool {
const T = @typeOf(x);
switch (T) {
f32 => {

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn isNan(x: var) -> bool {
pub fn isNan(x: var) bool {
const T = @typeOf(x);
switch (T) {
f32 => {
@ -21,7 +21,7 @@ pub fn isNan(x: var) -> bool {
// Note: A signalling nan is identical to a standard right now by may have a different bit
// representation in the future when required.
pub fn isSignalNan(x: var) -> bool {
pub fn isSignalNan(x: var) bool {
return isNan(x);
}

View File

@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn isNormal(x: var) -> bool {
pub fn isNormal(x: var) bool {
const T = @typeOf(x);
switch (T) {
f32 => {

View File

@ -11,7 +11,7 @@ const assert = std.debug.assert;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
pub fn ln(x: var) -> @typeOf(x) {
pub fn ln(x: var) @typeOf(x) {
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
@ -34,7 +34,7 @@ pub fn ln(x: var) -> @typeOf(x) {
}
}
pub fn ln_32(x_: f32) -> f32 {
pub fn ln_32(x_: f32) f32 {
@setFloatMode(this, @import("builtin").FloatMode.Strict);
const ln2_hi: f32 = 6.9313812256e-01;
@ -88,7 +88,7 @@ pub fn ln_32(x_: f32) -> f32 {
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
}
pub fn ln_64(x_: f64) -> f64 {
pub fn ln_64(x_: f64) f64 {
const ln2_hi: f64 = 6.93147180369123816490e-01;
const ln2_lo: f64 = 1.90821492927058770002e-10;
const Lg1: f64 = 6.666666666666735130e-01;

View File

@ -4,7 +4,7 @@ const builtin = @import("builtin");
const TypeId = builtin.TypeId;
const assert = std.debug.assert;
pub fn log(comptime T: type, base: T, x: T) -> T {
pub fn log(comptime T: type, base: T, x: T) T {
if (base == 2) {
return math.log2(x);
} else if (base == 10) {

View File

@ -11,7 +11,7 @@ const assert = std.debug.assert;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
pub fn log10(x: var) -> @typeOf(x) {
pub fn log10(x: var) @typeOf(x) {
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
@ -34,7 +34,7 @@ pub fn log10(x: var) -> @typeOf(x) {
}
}
pub fn log10_32(x_: f32) -> f32 {
pub fn log10_32(x_: f32) f32 {
const ivln10hi: f32 = 4.3432617188e-01;
const ivln10lo: f32 = -3.1689971365e-05;
const log10_2hi: f32 = 3.0102920532e-01;
@ -94,7 +94,7 @@ pub fn log10_32(x_: f32) -> f32 {
return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
}
pub fn log10_64(x_: f64) -> f64 {
pub fn log10_64(x_: f64) f64 {
const ivln10hi: f64 = 4.34294481878168880939e-01;
const ivln10lo: f64 = 2.50829467116452752298e-11;
const log10_2hi: f64 = 3.01029995663611771306e-01;

View File

@ -10,7 +10,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
pub fn log1p(x: var) -> @typeOf(x) {
pub fn log1p(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => log1p_32(x),
@ -19,7 +19,7 @@ pub fn log1p(x: var) -> @typeOf(x) {
};
}
fn log1p_32(x: f32) -> f32 {
fn log1p_32(x: f32) f32 {
const ln2_hi = 6.9313812256e-01;
const ln2_lo = 9.0580006145e-06;
const Lg1: f32 = 0xaaaaaa.0p-24;
@ -95,7 +95,7 @@ fn log1p_32(x: f32) -> f32 {
return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
}
fn log1p_64(x: f64) -> f64 {
fn log1p_64(x: f64) f64 {
const ln2_hi: f64 = 6.93147180369123816490e-01;
const ln2_lo: f64 = 1.90821492927058770002e-10;
const Lg1: f64 = 6.666666666666735130e-01;

View File

@ -11,7 +11,7 @@ const assert = std.debug.assert;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
pub fn log2(x: var) -> @typeOf(x) {
pub fn log2(x: var) @typeOf(x) {
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
@ -37,12 +37,12 @@ pub fn log2(x: var) -> @typeOf(x) {
}
}
pub fn log2_int(comptime T: type, x: T) -> T {
pub fn log2_int(comptime T: type, x: T) T {
assert(x != 0);
return T.bit_count - 1 - T(@clz(x));
}
pub fn log2_32(x_: f32) -> f32 {
pub fn log2_32(x_: f32) f32 {
const ivln2hi: f32 = 1.4428710938e+00;
const ivln2lo: f32 = -1.7605285393e-04;
const Lg1: f32 = 0xaaaaaa.0p-24;
@ -98,7 +98,7 @@ pub fn log2_32(x_: f32) -> f32 {
return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k);
}
pub fn log2_64(x_: f64) -> f64 {
pub fn log2_64(x_: f64) f64 {
const ivln2hi: f64 = 1.44269504072144627571e+00;
const ivln2lo: f64 = 1.67517131648865118353e-10;
const Lg1: f64 = 6.666666666666735130e-01;

View File

@ -7,7 +7,7 @@ const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
fn modf_result(comptime T: type) -> type {
fn modf_result(comptime T: type) type {
return struct {
fpart: T,
ipart: T,
@ -16,7 +16,7 @@ fn modf_result(comptime T: type) -> type {
pub const modf32_result = modf_result(f32);
pub const modf64_result = modf_result(f64);
pub fn modf(x: var) -> modf_result(@typeOf(x)) {
pub fn modf(x: var) modf_result(@typeOf(x)) {
const T = @typeOf(x);
return switch (T) {
f32 => modf32(x),
@ -25,7 +25,7 @@ pub fn modf(x: var) -> modf_result(@typeOf(x)) {
};
}
fn modf32(x: f32) -> modf32_result {
fn modf32(x: f32) modf32_result {
var result: modf32_result = undefined;
const u = @bitCast(u32, x);
@ -70,7 +70,7 @@ fn modf32(x: f32) -> modf32_result {
return result;
}
fn modf64(x: f64) -> modf64_result {
fn modf64(x: f64) modf64_result {
var result: modf64_result = undefined;
const u = @bitCast(u64, x);

View File

@ -1,6 +1,6 @@
const math = @import("index.zig");
pub fn nan(comptime T: type) -> T {
pub fn nan(comptime T: type) T {
return switch (T) {
f32 => @bitCast(f32, math.nan_u32),
f64 => @bitCast(f64, math.nan_u64),
@ -10,7 +10,7 @@ pub fn nan(comptime T: type) -> T {
// Note: A signalling nan is identical to a standard right now by may have a different bit
// representation in the future when required.
pub fn snan(comptime T: type) -> T {
pub fn snan(comptime T: type) T {
return switch (T) {
f32 => @bitCast(f32, math.nan_u32),
f64 => @bitCast(f64, math.nan_u64),

View File

@ -27,7 +27,7 @@ const math = std.math;
const assert = std.debug.assert;
// This implementation is taken from the go stlib, musl is a bit more complex.
pub fn pow(comptime T: type, x: T, y: T) -> T {
pub fn pow(comptime T: type, x: T, y: T) T {
@setFloatMode(this, @import("builtin").FloatMode.Strict);
@ -170,7 +170,7 @@ pub fn pow(comptime T: type, x: T, y: T) -> T {
return math.scalbn(a1, ae);
}
fn isOddInteger(x: f64) -> bool {
fn isOddInteger(x: f64) bool {
const r = math.modf(x);
return r.fpart == 0.0 and i64(r.ipart) & 1 == 1;
}

View File

@ -9,7 +9,7 @@ const assert = std.debug.assert;
const std = @import("../index.zig");
const math = std.math;
pub fn round(x: var) -> @typeOf(x) {
pub fn round(x: var) @typeOf(x) {
const T = @typeOf(x);
return switch (T) {
f32 => round32(x),
@ -18,7 +18,7 @@ pub fn round(x: var) -> @typeOf(x) {
};
}
fn round32(x_: f32) -> f32 {
fn round32(x_: f32) f32 {
var x = x_;
const u = @bitCast(u32, x);
const e = (u >> 23) & 0xFF;
@ -55,7 +55,7 @@ fn round32(x_: f32) -> f32 {
}
}
fn round64(x_: f64) -> f64 {
fn round64(x_: f64) f64 {
var x = x_;
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;

Some files were not shown because too many files have changed in this diff Show More