mirror of
https://github.com/ziglang/zig.git
synced 2025-01-05 18:00:25 +00:00
std: conform to style guidelines
This commit is contained in:
parent
0ae9023832
commit
37d167f6e0
62
doc/style.md
62
doc/style.md
@ -5,12 +5,68 @@ this documentation along with the compiler in order to provide a point of
|
||||
reference, should anyone wish to point to an authority on agreed upon Zig
|
||||
coding style.
|
||||
|
||||
## Whitespace
|
||||
|
||||
* 4 space indentation
|
||||
* `camelCaseFunctionName`
|
||||
* `TitleCaseTypeName`
|
||||
* `snake_case_variable_name`
|
||||
* Open braces on same line, unless you need to wrap.
|
||||
* If a list of things is longer than 2, put each item on its own line and
|
||||
exercise the abilty to put an extra comma at the end.
|
||||
* Line length: aim for 100; use common sense.
|
||||
|
||||
## Names
|
||||
|
||||
Roughly speaking: `camelCaseFunctionName`, `TitleCaseTypeName`,
|
||||
`snake_case_variable_name`. More precisely:
|
||||
|
||||
* If `x` is a `struct` (or an alias of a `struct`), then `x` should be `TitleCase`.
|
||||
* If `x` otherwise identifies a type, `x` should have `snake_case`.
|
||||
* If `x` is callable, and `x`'s return type is `type`, then `x` should be `TitleCase`.
|
||||
* If `x` is otherwise callable, then `x` should be `camelCase`.
|
||||
* Otherwise, `x` should be `snake_case`.
|
||||
|
||||
Acronyms, initialisms, proper nouns, or any other word that has capitalization
|
||||
rules in written English are subject to naming conventions just like any other
|
||||
word. Even acronyms that are only 2 letters long are subject to these
|
||||
conventions.
|
||||
|
||||
Examples:
|
||||
|
||||
```zig
|
||||
const namespace_name = @import("dir_name/file_name.zig");
|
||||
var global_var: i32;
|
||||
const const_name = 42;
|
||||
const primitive_type_alias = f32;
|
||||
const string_alias = []u8;
|
||||
|
||||
struct StructName {}
|
||||
const StructAlias = StructName;
|
||||
|
||||
fn functionName(param_name: TypeName) {
|
||||
var functionPointer = functionName;
|
||||
functionPointer();
|
||||
functionPointer = otherFunction;
|
||||
functionPointer();
|
||||
}
|
||||
const functionAlias = functionName;
|
||||
|
||||
fn ListTemplateFunction(ChildType: type, inline fixed_size: usize) -> type {
|
||||
struct ShortList(T: type, n: usize) {
|
||||
field_name: [n]T,
|
||||
fn methodName() {}
|
||||
}
|
||||
return List(ChildType, fixed_size);
|
||||
}
|
||||
|
||||
// The word XML loses its casing when used in Zig identifiers.
|
||||
const xml_document =
|
||||
\\<?xml version="1.0" encoding="UTF-8"?>
|
||||
\\<document>
|
||||
\\</document>
|
||||
;
|
||||
struct XmlParser {}
|
||||
|
||||
// The initials BE (Big Endian) are just another word in Zig identifier names.
|
||||
fn readU32Be() -> u32 {}
|
||||
```
|
||||
|
||||
See Zig standard library for examples.
|
||||
|
@ -16,7 +16,7 @@ pub fn main(args: [][]u8) -> %void {
|
||||
} else {
|
||||
var is = io.InStream.open(arg) %% |err| {
|
||||
%%io.stderr.printf("Unable to open file: ");
|
||||
%%io.stderr.printf(@err_name(err));
|
||||
%%io.stderr.printf(@errName(err));
|
||||
%%io.stderr.printf("\n");
|
||||
return err;
|
||||
};
|
||||
@ -45,7 +45,7 @@ fn cat_stream(is: io.InStream) -> %void {
|
||||
while (true) {
|
||||
const bytes_read = is.read(buf) %% |err| {
|
||||
%%io.stderr.printf("Unable to read from stream: ");
|
||||
%%io.stderr.printf(@err_name(err));
|
||||
%%io.stderr.printf(@errName(err));
|
||||
%%io.stderr.printf("\n");
|
||||
return err;
|
||||
};
|
||||
@ -56,7 +56,7 @@ fn cat_stream(is: io.InStream) -> %void {
|
||||
|
||||
io.stdout.write(buf[0...bytes_read]) %% |err| {
|
||||
%%io.stderr.printf("Unable to write to stdout: ");
|
||||
%%io.stderr.printf(@err_name(err));
|
||||
%%io.stderr.printf(@errName(err));
|
||||
%%io.stderr.printf("\n");
|
||||
return err;
|
||||
};
|
||||
|
@ -6,11 +6,12 @@ const os = std.os;
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
%%io.stdout.printf("Welcome to the Guess Number Game in Zig.\n");
|
||||
|
||||
var seed: [@sizeof(usize)]u8 = undefined;
|
||||
var seed: [@sizeOf(usize)]u8 = undefined;
|
||||
%%os.get_random_bytes(seed);
|
||||
var rand = Rand.init(([]usize)(seed)[0]);
|
||||
var rand: Rand = undefined;
|
||||
rand.init(([]usize)(seed)[0]);
|
||||
|
||||
const answer = rand.range_unsigned(u8, 0, 100) + 1;
|
||||
const answer = rand.rangeUnsigned(u8, 0, 100) + 1;
|
||||
|
||||
while (true) {
|
||||
%%io.stdout.printf("\nGuess a number between 1 and 100: ");
|
||||
@ -21,7 +22,7 @@ pub fn main(args: [][]u8) -> %void {
|
||||
return err;
|
||||
};
|
||||
|
||||
const guess = io.parse_unsigned(u8, line_buf[0...line_len - 1], 10) %% {
|
||||
const guess = io.parseUnsigned(u8, line_buf[0...line_len - 1], 10) %% {
|
||||
%%io.stdout.printf("Invalid number.\n");
|
||||
continue;
|
||||
};
|
||||
|
@ -5206,7 +5206,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
add_node_error(g, expr_node,
|
||||
buf_sprintf("type '%s' not eligible for @typeof", buf_ptr(&type_entry->name)));
|
||||
buf_sprintf("type '%s' not eligible for @typeOf", buf_ptr(&type_entry->name)));
|
||||
return g->builtin_types.entry_invalid;
|
||||
case TypeTableEntryIdMetaType:
|
||||
case TypeTableEntryIdVoid:
|
||||
|
@ -4642,7 +4642,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
}
|
||||
{
|
||||
BuiltinFnEntry *builtin_fn = create_builtin_fn_with_arg_count(g, BuiltinFnIdReturnAddress,
|
||||
"return_address", 0);
|
||||
"returnAddress", 0);
|
||||
builtin_fn->return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
|
||||
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(builtin_fn->return_type->type_ref,
|
||||
@ -4652,7 +4652,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
}
|
||||
{
|
||||
BuiltinFnEntry *builtin_fn = create_builtin_fn_with_arg_count(g, BuiltinFnIdFrameAddress,
|
||||
"frame_address", 0);
|
||||
"frameAddress", 0);
|
||||
builtin_fn->return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
|
||||
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(builtin_fn->return_type->type_ref,
|
||||
@ -4708,33 +4708,33 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
|
||||
g->memset_fn_val = builtin_fn->fn_val;
|
||||
}
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdSizeof, "sizeof", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdAlignof, "alignof", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMaxValue, "max_value", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMinValue, "min_value", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMemberCount, "member_count", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdTypeof, "typeof", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdAddWithOverflow, "add_with_overflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdSubWithOverflow, "sub_with_overflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMulWithOverflow, "mul_with_overflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdShlWithOverflow, "shl_with_overflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCInclude, "c_include", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileVar, "compile_var", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdConstEval, "const_eval", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdSizeof, "sizeOf", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdAlignof, "alignOf", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMaxValue, "maxValue", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMinValue, "minValue", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMemberCount, "memberCount", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdTypeof, "typeOf", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdMulWithOverflow, "mulWithOverflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdShlWithOverflow, "shlWithOverflow", 4);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCInclude, "cInclude", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "cDefine", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "cUndef", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileVar, "compileVar", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdConstEval, "constEval", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCtz, "ctz", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdClz, "clz", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdImport, "import", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "c_import", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdErrName, "err_name", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdEmbedFile, "embed_file", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "cImport", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdErrName, "errName", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdEmbedFile, "embedFile", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCmpExchange, "cmpxchg", 5);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdFence, "fence", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdDivExact, "div_exact", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdDivExact, "divExact", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdTruncate, "truncate", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compile_err", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdIntType, "int_type", 2);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compileErr", 1);
|
||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdIntType, "intType", 2);
|
||||
}
|
||||
|
||||
static void init(CodeGen *g, Buf *source_path) {
|
||||
|
@ -4,7 +4,7 @@ const root = @import("@root");
|
||||
const linux = @import("linux.zig");
|
||||
const cstr = @import("cstr.zig");
|
||||
|
||||
const want_start_symbol = switch(@compile_var("os")) {
|
||||
const want_start_symbol = switch(@compileVar("os")) {
|
||||
linux => true,
|
||||
else => false,
|
||||
};
|
||||
@ -16,7 +16,7 @@ var argv: &&u8 = undefined;
|
||||
#attribute("naked")
|
||||
#condition(want_start_symbol)
|
||||
export fn _start() -> unreachable {
|
||||
switch (@compile_var("arch")) {
|
||||
switch (@compileVar("arch")) {
|
||||
x86_64 => {
|
||||
argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize));
|
||||
argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
|
||||
@ -25,12 +25,12 @@ export fn _start() -> unreachable {
|
||||
argc = asm("mov (%%esp), %[argc]": [argc] "=r" (-> usize));
|
||||
argv = asm("lea 0x4(%%esp), %[argv]": [argv] "=r" (-> &&u8));
|
||||
},
|
||||
else => @compile_err("unsupported arch"),
|
||||
else => @compileErr("unsupported arch"),
|
||||
}
|
||||
call_main_and_exit()
|
||||
callMainAndExit()
|
||||
}
|
||||
|
||||
fn call_main() -> %void {
|
||||
fn callMain() -> %void {
|
||||
var args: [argc][]u8 = undefined;
|
||||
for (args) |arg, i| {
|
||||
const ptr = argv[i];
|
||||
@ -39,8 +39,8 @@ fn call_main() -> %void {
|
||||
return root.main(args);
|
||||
}
|
||||
|
||||
fn call_main_and_exit() -> unreachable {
|
||||
call_main() %% linux.exit(1);
|
||||
fn callMainAndExit() -> unreachable {
|
||||
callMain() %% linux.exit(1);
|
||||
linux.exit(0);
|
||||
}
|
||||
|
||||
@ -48,6 +48,6 @@ fn call_main_and_exit() -> unreachable {
|
||||
export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
|
||||
argc = usize(c_argc);
|
||||
argv = c_argv;
|
||||
call_main() %% return 1;
|
||||
callMain() %% return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ const si_int = c_int;
|
||||
const su_int = c_uint;
|
||||
|
||||
const udwords = [2]su_int;
|
||||
const low = if (@compile_var("is_big_endian")) 1 else 0;
|
||||
const low = if (@compileVar("is_big_endian")) 1 else 0;
|
||||
const high = 1 - low;
|
||||
|
||||
#debug_safety(false)
|
||||
@ -20,8 +20,8 @@ fn du_int_to_udwords(x: du_int) -> udwords {
|
||||
|
||||
#debug_safety(false)
|
||||
export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||
const n_uword_bits = @sizeof(su_int) * CHAR_BIT;
|
||||
const n_udword_bits = @sizeof(du_int) * CHAR_BIT;
|
||||
const n_uword_bits = @sizeOf(su_int) * CHAR_BIT;
|
||||
const n_udword_bits = @sizeOf(du_int) * CHAR_BIT;
|
||||
var n = du_int_to_udwords(a);
|
||||
var d = du_int_to_udwords(b);
|
||||
var q: udwords = undefined;
|
||||
@ -79,7 +79,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||
r[high] = n[high] & (d[high] - 1);
|
||||
*rem = *(&du_int)(&r[0]);
|
||||
}
|
||||
return n[high] >> @ctz(@typeof(d[high]), d[high]);
|
||||
return n[high] >> @ctz(@typeOf(d[high]), d[high]);
|
||||
}
|
||||
// K K
|
||||
// ---
|
||||
@ -114,7 +114,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
|
||||
if (d[low] == 1) {
|
||||
return *(&du_int)(&n[0]);
|
||||
}
|
||||
sr = @ctz(@typeof(d[low]), d[low]);
|
||||
sr = @ctz(@typeOf(d[low]), d[low]);
|
||||
q[high] = n[high] >> sr;
|
||||
q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
|
||||
return *(&du_int)(&q[0]);
|
||||
|
68
std/cstr.zig
68
std/cstr.zig
@ -24,11 +24,11 @@ pub fn cmp(a: &const u8, b: &const u8) -> i32 {
|
||||
return a[index] - b[index];
|
||||
}
|
||||
|
||||
pub fn to_slice_const(str: &const u8) -> []const u8 {
|
||||
pub fn toSliceConst(str: &const u8) -> []const u8 {
|
||||
return str[0...strlen(str)];
|
||||
}
|
||||
|
||||
pub fn to_slice(str: &u8) -> []u8 {
|
||||
pub fn toSlice(str: &u8) -> []u8 {
|
||||
return str[0...strlen(str)];
|
||||
}
|
||||
|
||||
@ -46,25 +46,25 @@ pub struct CBuf {
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init_from_mem(self: &CBuf, allocator: &Allocator, m: []const u8) -> %void {
|
||||
pub fn initFromMem(self: &CBuf, allocator: &Allocator, m: []const u8) -> %void {
|
||||
self.init(allocator);
|
||||
%return self.resize(m.len);
|
||||
mem.copy(u8, self.list.items, m);
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init_from_cstr(self: &CBuf, allocator: &Allocator, s: &const u8) -> %void {
|
||||
self.init_from_mem(allocator, s[0...strlen(s)])
|
||||
pub fn initFromCStr(self: &CBuf, allocator: &Allocator, s: &const u8) -> %void {
|
||||
self.initFromMem(allocator, s[0...strlen(s)])
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init_from_cbuf(self: &CBuf, cbuf: &const CBuf) -> %void {
|
||||
self.init_from_mem(cbuf.list.allocator, cbuf.list.items[0...cbuf.len()])
|
||||
pub fn initFromCBuf(self: &CBuf, cbuf: &const CBuf) -> %void {
|
||||
self.initFromMem(cbuf.list.allocator, cbuf.list.items[0...cbuf.len()])
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init_from_slice(self: &CBuf, other: &const CBuf, start: usize, end: usize) -> %void {
|
||||
self.init_from_mem(other.list.allocator, other.list.items[start...end])
|
||||
pub fn initFromSlice(self: &CBuf, other: &const CBuf, start: usize, end: usize) -> %void {
|
||||
self.initFromMem(other.list.allocator, other.list.items[start...end])
|
||||
}
|
||||
|
||||
pub fn deinit(self: &CBuf) {
|
||||
@ -80,66 +80,66 @@ pub struct CBuf {
|
||||
return self.list.len - 1;
|
||||
}
|
||||
|
||||
pub fn append_mem(self: &CBuf, m: []const u8) -> %void {
|
||||
pub fn appendMem(self: &CBuf, m: []const u8) -> %void {
|
||||
const old_len = self.len();
|
||||
%return self.resize(old_len + m.len);
|
||||
mem.copy(u8, self.list.items[old_len...], m);
|
||||
}
|
||||
|
||||
pub fn append_cstr(self: &CBuf, s: &const u8) -> %void {
|
||||
self.append_mem(s[0...strlen(s)])
|
||||
pub fn appendCStr(self: &CBuf, s: &const u8) -> %void {
|
||||
self.appendMem(s[0...strlen(s)])
|
||||
}
|
||||
|
||||
pub fn append_char(self: &CBuf, c: u8) -> %void {
|
||||
pub fn appendChar(self: &CBuf, c: u8) -> %void {
|
||||
%return self.resize(self.len() + 1);
|
||||
self.list.items[self.len() - 1] = c;
|
||||
}
|
||||
|
||||
pub fn eql_mem(self: &const CBuf, m: []const u8) -> bool {
|
||||
pub fn eqlMem(self: &const CBuf, m: []const u8) -> bool {
|
||||
if (self.len() != m.len) return false;
|
||||
return mem.cmp(u8, self.list.items[0...m.len], m) == mem.Cmp.Equal;
|
||||
}
|
||||
|
||||
pub fn eql_cstr(self: &const CBuf, s: &const u8) -> bool {
|
||||
self.eql_mem(s[0...strlen(s)])
|
||||
pub fn eqlCStr(self: &const CBuf, s: &const u8) -> bool {
|
||||
self.eqlMem(s[0...strlen(s)])
|
||||
}
|
||||
|
||||
pub fn eql_cbuf(self: &const CBuf, other: &const CBuf) -> bool {
|
||||
self.eql_mem(other.list.items[0...other.len()])
|
||||
pub fn eqlCBuf(self: &const CBuf, other: &const CBuf) -> bool {
|
||||
self.eqlMem(other.list.items[0...other.len()])
|
||||
}
|
||||
|
||||
pub fn starts_with_mem(self: &const CBuf, m: []const u8) -> bool {
|
||||
pub fn startsWithMem(self: &const CBuf, m: []const u8) -> bool {
|
||||
if (self.len() < m.len) return false;
|
||||
return mem.cmp(u8, self.list.items[0...m.len], m) == mem.Cmp.Equal;
|
||||
}
|
||||
|
||||
pub fn starts_with_cbuf(self: &const CBuf, other: &const CBuf) -> bool {
|
||||
self.starts_with_mem(other.list.items[0...other.len()])
|
||||
pub fn startsWithCBuf(self: &const CBuf, other: &const CBuf) -> bool {
|
||||
self.startsWithMem(other.list.items[0...other.len()])
|
||||
}
|
||||
|
||||
pub fn starts_with_cstr(self: &const CBuf, s: &const u8) -> bool {
|
||||
self.starts_with_mem(s[0...strlen(s)])
|
||||
pub fn startsWithCStr(self: &const CBuf, s: &const u8) -> bool {
|
||||
self.startsWithMem(s[0...strlen(s)])
|
||||
}
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn test_simple_cbuf() {
|
||||
fn testSimpleCBuf() {
|
||||
var buf: CBuf = undefined;
|
||||
buf.init(&debug.global_allocator);
|
||||
assert(buf.len() == 0);
|
||||
%%buf.append_cstr(c"hello");
|
||||
%%buf.append_char(' ');
|
||||
%%buf.append_mem("world");
|
||||
assert(buf.eql_cstr(c"hello world"));
|
||||
assert(buf.eql_mem("hello world"));
|
||||
%%buf.appendCStr(c"hello");
|
||||
%%buf.appendChar(' ');
|
||||
%%buf.appendMem("world");
|
||||
assert(buf.eqlCStr(c"hello world"));
|
||||
assert(buf.eqlMem("hello world"));
|
||||
|
||||
var buf2: CBuf = undefined;
|
||||
%%buf2.init_from_cbuf(&buf);
|
||||
assert(buf.eql_cbuf(&buf2));
|
||||
%%buf2.initFromCBuf(&buf);
|
||||
assert(buf.eqlCBuf(&buf2));
|
||||
|
||||
assert(buf.starts_with_mem("hell"));
|
||||
assert(buf.starts_with_cstr(c"hell"));
|
||||
assert(buf.startsWithMem("hell"));
|
||||
assert(buf.startsWithCStr(c"hell"));
|
||||
|
||||
%%buf2.resize(4);
|
||||
assert(buf.starts_with_cbuf(&buf2));
|
||||
assert(buf.startsWithCBuf(&buf2));
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ pub fn assert(b: bool) {
|
||||
}
|
||||
|
||||
pub fn printStackTrace() {
|
||||
var maybe_fp: ?&const u8 = @frame_address();
|
||||
var maybe_fp: ?&const u8 = @frameAddress();
|
||||
while (true) {
|
||||
const fp = maybe_fp ?? break;
|
||||
const return_address = *(&const usize)(usize(fp) + @sizeof(usize));
|
||||
const return_address = *(&const usize)(usize(fp) + @sizeOf(usize));
|
||||
%%io.stderr.print_u64(return_address);
|
||||
%%io.stderr.printf("\n");
|
||||
maybe_fp = *(&const ?&const u8)(fp);
|
||||
@ -17,9 +17,9 @@ pub fn printStackTrace() {
|
||||
}
|
||||
|
||||
pub var global_allocator = Allocator {
|
||||
.alloc_fn = globalAlloc,
|
||||
.realloc_fn = globalRealloc,
|
||||
.free_fn = globalFree,
|
||||
.allocFn = globalAlloc,
|
||||
.reallocFn = globalRealloc,
|
||||
.freeFn = globalFree,
|
||||
.context = null,
|
||||
};
|
||||
|
||||
|
@ -4,27 +4,27 @@ const math = @import("math.zig");
|
||||
const mem = @import("mem.zig");
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
const want_modification_safety = !@compile_var("is_release");
|
||||
const want_modification_safety = !@compileVar("is_release");
|
||||
const debug_u32 = if (want_modification_safety) u32 else void;
|
||||
|
||||
pub fn HashMap(inline K: type, inline V: type, inline hash: fn(key: K)->u32,
|
||||
inline eql: fn(a: K, b: K)->bool) -> type
|
||||
{
|
||||
SmallHashMap(K, V, hash, eql, @sizeof(usize))
|
||||
SmallHashMap(K, V, hash, eql, @sizeOf(usize))
|
||||
}
|
||||
|
||||
pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)->bool, STATIC_SIZE: usize) {
|
||||
pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)->bool, static_size: usize) {
|
||||
entries: []Entry,
|
||||
size: usize,
|
||||
max_distance_from_start_index: usize,
|
||||
allocator: &Allocator,
|
||||
// if the hash map is small enough, we use linear search through these
|
||||
// entries instead of allocating memory
|
||||
prealloc_entries: [STATIC_SIZE]Entry,
|
||||
prealloc_entries: [static_size]Entry,
|
||||
// this is used to detect bugs where a hashtable is edited while an iterator is running.
|
||||
modification_count: debug_u32,
|
||||
|
||||
const Self = SmallHashMap(K, V, hash, eql, STATIC_SIZE);
|
||||
const Self = SmallHashMap(K, V, hash, eql, static_size);
|
||||
|
||||
pub struct Entry {
|
||||
used: bool,
|
||||
@ -80,11 +80,11 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
}
|
||||
hm.size = 0;
|
||||
hm.max_distance_from_start_index = 0;
|
||||
hm.increment_modification_count();
|
||||
hm.incrementModificationCount();
|
||||
}
|
||||
|
||||
pub fn put(hm: &Self, key: K, value: V) -> %void {
|
||||
hm.increment_modification_count();
|
||||
hm.incrementModificationCount();
|
||||
|
||||
const resize = if (hm.entries.ptr == &hm.prealloc_entries[0]) {
|
||||
// preallocated entries table is full
|
||||
@ -95,11 +95,11 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
};
|
||||
if (resize) {
|
||||
const old_entries = hm.entries;
|
||||
%return hm.init_capacity(hm.entries.len * 2);
|
||||
%return hm.initCapacity(hm.entries.len * 2);
|
||||
// dump all of the old elements into the new table
|
||||
for (old_entries) |*old_entry| {
|
||||
if (old_entry.used) {
|
||||
hm.internal_put(old_entry.key, old_entry.value);
|
||||
hm.internalPut(old_entry.key, old_entry.value);
|
||||
}
|
||||
}
|
||||
if (old_entries.ptr != &hm.prealloc_entries[0]) {
|
||||
@ -107,16 +107,16 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
}
|
||||
}
|
||||
|
||||
hm.internal_put(key, value);
|
||||
hm.internalPut(key, value);
|
||||
}
|
||||
|
||||
pub fn get(hm: &Self, key: K) -> ?&Entry {
|
||||
return hm.internal_get(key);
|
||||
return hm.internalGet(key);
|
||||
}
|
||||
|
||||
pub fn remove(hm: &Self, key: K) {
|
||||
hm.increment_modification_count();
|
||||
const start_index = hm.key_to_index(key);
|
||||
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) {
|
||||
const index = (start_index + roll_over) % hm.entries.len;
|
||||
var entry = &hm.entries[index];
|
||||
@ -142,7 +142,7 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
unreachable{} // key not found
|
||||
}
|
||||
|
||||
pub fn entry_iterator(hm: &Self) -> Iterator {
|
||||
pub fn entryIterator(hm: &Self) -> Iterator {
|
||||
return Iterator {
|
||||
.hm = hm,
|
||||
.count = 0,
|
||||
@ -151,7 +151,7 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
};
|
||||
}
|
||||
|
||||
fn init_capacity(hm: &Self, capacity: usize) -> %void {
|
||||
fn initCapacity(hm: &Self, capacity: usize) -> %void {
|
||||
hm.entries = %return hm.allocator.alloc(Entry, capacity);
|
||||
hm.size = 0;
|
||||
hm.max_distance_from_start_index = 0;
|
||||
@ -160,16 +160,16 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
}
|
||||
}
|
||||
|
||||
fn increment_modification_count(hm: &Self) {
|
||||
fn incrementModificationCount(hm: &Self) {
|
||||
if (want_modification_safety) {
|
||||
hm.modification_count +%= 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn internal_put(hm: &Self, orig_key: K, orig_value: V) {
|
||||
fn internalPut(hm: &Self, orig_key: K, orig_value: V) {
|
||||
var key = orig_key;
|
||||
var value = orig_value;
|
||||
const start_index = hm.key_to_index(key);
|
||||
const start_index = hm.keyToIndex(key);
|
||||
var roll_over: usize = 0;
|
||||
var distance_from_start_index: usize = 0;
|
||||
while (roll_over < hm.entries.len; {roll_over += 1; distance_from_start_index += 1}) {
|
||||
@ -214,8 +214,8 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
unreachable{} // put into a full map
|
||||
}
|
||||
|
||||
fn internal_get(hm: &Self, key: K) -> ?&Entry {
|
||||
const start_index = hm.key_to_index(key);
|
||||
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;
|
||||
const entry = &hm.entries[index];
|
||||
@ -226,13 +226,13 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
return null;
|
||||
}
|
||||
|
||||
fn key_to_index(hm: &Self, key: K) -> usize {
|
||||
fn keyToIndex(hm: &Self, key: K) -> usize {
|
||||
return usize(hash(key)) % hm.entries.len;
|
||||
}
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn basic_hash_map_test() {
|
||||
fn basicHashMapTest() {
|
||||
var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;
|
||||
map.init(&debug.global_allocator);
|
||||
defer map.deinit();
|
||||
|
@ -9,7 +9,7 @@ pub const list = @import("list.zig");
|
||||
pub const hash_map = @import("hash_map.zig");
|
||||
pub const mem = @import("mem.zig");
|
||||
pub const debug = @import("debug.zig");
|
||||
pub const linux = switch(@compile_var("os")) {
|
||||
pub const linux = switch(@compileVar("os")) {
|
||||
linux => @import("linux.zig"),
|
||||
else => null_import,
|
||||
};
|
||||
|
50
std/io.zig
50
std/io.zig
@ -63,7 +63,7 @@ pub struct OutStream {
|
||||
buffer: [buffer_size]u8,
|
||||
index: usize,
|
||||
|
||||
pub fn write_byte(os: &OutStream, b: u8) -> %void {
|
||||
pub fn writeByte(os: &OutStream, b: u8) -> %void {
|
||||
if (os.buffer.len == os.index) %return os.flush();
|
||||
os.buffer[os.index] = b;
|
||||
os.index += 1;
|
||||
@ -71,7 +71,7 @@ pub struct OutStream {
|
||||
|
||||
pub fn write(os: &OutStream, bytes: []const u8) -> %usize {
|
||||
var src_bytes_left = bytes.len;
|
||||
var src_index: @typeof(bytes.len) = 0;
|
||||
var src_index: @typeOf(bytes.len) = 0;
|
||||
const dest_space_left = os.buffer.len - os.index;
|
||||
|
||||
while (src_bytes_left > 0) {
|
||||
@ -98,7 +98,7 @@ pub struct OutStream {
|
||||
if (os.index + max_u64_base10_digits >= os.buffer.len) {
|
||||
%return os.flush();
|
||||
}
|
||||
const amt_printed = buf_print_u64(os.buffer[os.index...], x);
|
||||
const amt_printed = bufPrintUnsigned(u64, os.buffer[os.index...], x);
|
||||
os.index += amt_printed;
|
||||
|
||||
return amt_printed;
|
||||
@ -108,7 +108,7 @@ pub struct OutStream {
|
||||
if (os.index + max_u64_base10_digits >= os.buffer.len) {
|
||||
%return os.flush();
|
||||
}
|
||||
const amt_printed = buf_print_i64(os.buffer[os.index...], x);
|
||||
const amt_printed = bufPrintSigned(i64, os.buffer[os.index...], x);
|
||||
os.index += amt_printed;
|
||||
|
||||
return amt_printed;
|
||||
@ -116,7 +116,7 @@ pub struct OutStream {
|
||||
|
||||
pub fn flush(os: &OutStream) -> %void {
|
||||
const write_ret = linux.write(os.fd, &os.buffer[0], os.index);
|
||||
const write_err = linux.get_errno(write_ret);
|
||||
const write_err = linux.getErrno(write_ret);
|
||||
if (write_err > 0) {
|
||||
return switch (write_err) {
|
||||
errno.EINVAL => unreachable{},
|
||||
@ -135,7 +135,7 @@ pub struct OutStream {
|
||||
|
||||
pub fn close(os: &OutStream) -> %void {
|
||||
const close_ret = linux.close(os.fd);
|
||||
const close_err = linux.get_errno(close_ret);
|
||||
const close_err = linux.getErrno(close_ret);
|
||||
if (close_err > 0) {
|
||||
return switch (close_err) {
|
||||
errno.EIO => error.Io,
|
||||
@ -152,7 +152,7 @@ pub struct InStream {
|
||||
|
||||
pub fn open(path: []u8) -> %InStream {
|
||||
const fd = linux.open(path, linux.O_LARGEFILE|linux.O_RDONLY, 0);
|
||||
const fd_err = linux.get_errno(fd);
|
||||
const fd_err = linux.getErrno(fd);
|
||||
if (fd_err > 0) {
|
||||
return switch (fd_err) {
|
||||
errno.EFAULT => unreachable{},
|
||||
@ -180,7 +180,7 @@ pub struct InStream {
|
||||
|
||||
pub fn read(is: &InStream, buf: []u8) -> %usize {
|
||||
const amt_read = linux.read(is.fd, &buf[0], buf.len);
|
||||
const read_err = linux.get_errno(amt_read);
|
||||
const read_err = linux.getErrno(amt_read);
|
||||
if (read_err > 0) {
|
||||
return switch (read_err) {
|
||||
errno.EINVAL => unreachable{},
|
||||
@ -196,7 +196,7 @@ pub struct InStream {
|
||||
|
||||
pub fn close(is: &InStream) -> %void {
|
||||
const close_ret = linux.close(is.fd);
|
||||
const close_err = linux.get_errno(close_ret);
|
||||
const close_err = linux.getErrno(close_ret);
|
||||
if (close_err > 0) {
|
||||
return switch (close_err) {
|
||||
errno.EIO => error.Io,
|
||||
@ -208,20 +208,20 @@ pub struct InStream {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_unsigned(inline T: type, buf: []u8, radix: u8) -> %T {
|
||||
pub fn parseUnsigned(inline T: type, buf: []u8, radix: u8) -> %T {
|
||||
var x: T = 0;
|
||||
|
||||
for (buf) |c| {
|
||||
const digit = %return char_to_digit(c, radix);
|
||||
x = %return math.mul_overflow(T, x, radix);
|
||||
x = %return math.add_overflow(T, x, digit);
|
||||
const digit = %return charToDigit(c, radix);
|
||||
x = %return math.mulOverflow(T, x, radix);
|
||||
x = %return math.addOverflow(T, x, digit);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
pub error InvalidChar;
|
||||
fn char_to_digit(c: u8, radix: u8) -> %u8 {
|
||||
fn charToDigit(c: u8, radix: u8) -> %u8 {
|
||||
const value = if ('0' <= c && c <= '9') {
|
||||
c - '0'
|
||||
} else if ('A' <= c && c <= 'Z') {
|
||||
@ -234,21 +234,17 @@ fn char_to_digit(c: u8, radix: u8) -> %u8 {
|
||||
return if (value >= radix) error.InvalidChar else value;
|
||||
}
|
||||
|
||||
pub fn buf_print_signed(inline T: type, out_buf: []u8, x: T) -> usize {
|
||||
const uint = @int_type(false, T.bit_count);
|
||||
pub fn bufPrintSigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
||||
const uint = @intType(false, T.bit_count);
|
||||
if (x < 0) {
|
||||
out_buf[0] = '-';
|
||||
return 1 + buf_print_unsigned(uint, out_buf[1...], uint(-(x + 1)) + 1);
|
||||
return 1 + bufPrintUnsigned(uint, out_buf[1...], uint(-(x + 1)) + 1);
|
||||
} else {
|
||||
return buf_print_unsigned(uint, out_buf, uint(x));
|
||||
return bufPrintUnsigned(uint, out_buf, uint(x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buf_print_i64(out_buf: []u8, x: i64) -> usize {
|
||||
buf_print_signed(i64, out_buf, x)
|
||||
}
|
||||
|
||||
pub fn buf_print_unsigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
||||
pub fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
||||
var buf: [max_u64_base10_digits]u8 = undefined;
|
||||
var a = x;
|
||||
var index: usize = buf.len;
|
||||
@ -269,13 +265,9 @@ pub fn buf_print_unsigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
||||
return len;
|
||||
}
|
||||
|
||||
pub fn buf_print_u64(out_buf: []u8, x: u64) -> usize {
|
||||
buf_print_unsigned(u64, out_buf, x)
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn parse_u64_digit_too_big() {
|
||||
parse_unsigned(u64, "123a", 10) %% |err| {
|
||||
fn parseU64DigitTooBig() {
|
||||
parseUnsigned(u64, "123a", 10) %% |err| {
|
||||
if (err == error.InvalidChar) return;
|
||||
unreachable{};
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
const arch = switch (@compile_var("arch")) {
|
||||
const arch = switch (@compileVar("arch")) {
|
||||
x86_64 => @import("linux_x86_64.zig"),
|
||||
i386 => @import("linux_i386.zig"),
|
||||
else => @compile_err("unsupported arch"),
|
||||
@ -221,7 +221,7 @@ pub const AF_VSOCK = PF_VSOCK;
|
||||
pub const AF_MAX = PF_MAX;
|
||||
|
||||
/// Get the errno from a syscall return value, or 0 for no error.
|
||||
pub fn get_errno(r: usize) -> usize {
|
||||
pub fn getErrno(r: usize) -> usize {
|
||||
const signed_r = *(&isize)(&r);
|
||||
if (signed_r > -4096 && signed_r < 0) usize(-signed_r) else 0
|
||||
}
|
||||
@ -291,22 +291,22 @@ const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, };
|
||||
|
||||
pub fn raise(sig: i32) -> i32 {
|
||||
var set: sigset_t = undefined;
|
||||
block_app_signals(&set);
|
||||
blockAppSignals(&set);
|
||||
const tid = i32(arch.syscall0(arch.SYS_gettid));
|
||||
const ret = i32(arch.syscall2(arch.SYS_tkill, usize(tid), usize(sig)));
|
||||
restore_signals(&set);
|
||||
restoreSignals(&set);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn block_all_signals(set: &sigset_t) {
|
||||
fn blockAllSignals(set: &sigset_t) {
|
||||
arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, usize(&all_mask), usize(set), NSIG/8);
|
||||
}
|
||||
|
||||
fn block_app_signals(set: &sigset_t) {
|
||||
fn blockAppSignals(set: &sigset_t) {
|
||||
arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, usize(&app_mask), usize(set), NSIG/8);
|
||||
}
|
||||
|
||||
fn restore_signals(set: &sigset_t) {
|
||||
fn restoreSignals(set: &sigset_t) {
|
||||
arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, usize(set), 0, NSIG/8);
|
||||
}
|
||||
|
||||
@ -442,7 +442,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
|
||||
// }
|
||||
//
|
||||
// const socket_ret = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
|
||||
// const socket_err = get_errno(socket_ret);
|
||||
// const socket_err = getErrno(socket_ret);
|
||||
// if (socket_err > 0) {
|
||||
// return error.SystemResources;
|
||||
// }
|
||||
@ -451,7 +451,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
|
||||
// ifr.ifr_name[name.len] = 0;
|
||||
// const ioctl_ret = ioctl(socket_fd, SIOCGIFINDEX, &ifr);
|
||||
// close(socket_fd);
|
||||
// const ioctl_err = get_errno(ioctl_ret);
|
||||
// const ioctl_err = getErrno(ioctl_ret);
|
||||
// if (ioctl_err > 0) {
|
||||
// return error.Io;
|
||||
// }
|
||||
|
20
std/list.zig
20
std/list.zig
@ -4,17 +4,17 @@ const mem = @import("mem.zig");
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
pub fn List(inline T: type) -> type {
|
||||
SmallList(T, @sizeof(usize))
|
||||
SmallList(T, @sizeOf(usize))
|
||||
}
|
||||
|
||||
// TODO: make sure that setting STATIC_SIZE to 0 codegens to the same code
|
||||
// as if this were programmed without STATIC_SIZE at all.
|
||||
pub struct SmallList(T: type, STATIC_SIZE: usize) {
|
||||
const Self = SmallList(T, STATIC_SIZE);
|
||||
// TODO: make sure that setting static_size to 0 codegens to the same code
|
||||
// as if this were programmed without static_size at all.
|
||||
pub struct SmallList(T: type, static_size: usize) {
|
||||
const Self = SmallList(T, static_size);
|
||||
|
||||
items: []T,
|
||||
len: usize,
|
||||
prealloc_items: [STATIC_SIZE]T,
|
||||
prealloc_items: [static_size]T,
|
||||
allocator: &Allocator,
|
||||
|
||||
pub fn init(l: &Self, allocator: &Allocator) {
|
||||
@ -31,17 +31,17 @@ pub struct SmallList(T: type, STATIC_SIZE: usize) {
|
||||
|
||||
pub fn append(l: &Self, item: T) -> %void {
|
||||
const new_length = l.len + 1;
|
||||
%return l.ensure_capacity(new_length);
|
||||
%return l.ensureCapacity(new_length);
|
||||
l.items[l.len] = item;
|
||||
l.len = new_length;
|
||||
}
|
||||
|
||||
pub fn resize(l: &Self, new_len: usize) -> %void {
|
||||
%return l.ensure_capacity(new_len);
|
||||
%return l.ensureCapacity(new_len);
|
||||
l.len = new_len;
|
||||
}
|
||||
|
||||
pub fn ensure_capacity(l: &Self, new_capacity: usize) -> %void {
|
||||
pub fn ensureCapacity(l: &Self, new_capacity: usize) -> %void {
|
||||
const old_capacity = l.items.len;
|
||||
var better_capacity = old_capacity;
|
||||
while (better_capacity < new_capacity) {
|
||||
@ -59,7 +59,7 @@ pub struct SmallList(T: type, STATIC_SIZE: usize) {
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn basic_list_test() {
|
||||
fn basicListTest() {
|
||||
var list: List(i32) = undefined;
|
||||
list.init(&debug.global_allocator);
|
||||
defer list.deinit();
|
||||
|
40
std/math.zig
40
std/math.zig
@ -4,34 +4,6 @@ pub enum Cmp {
|
||||
Less,
|
||||
}
|
||||
|
||||
pub fn f64_from_bits(bits: u64) -> f64 {
|
||||
*(&f64)(&bits)
|
||||
}
|
||||
|
||||
pub fn f64_to_bits(f: f64) -> u64 {
|
||||
*(&u64)(&f)
|
||||
}
|
||||
|
||||
pub fn f64_get_pos_inf() -> f64 {
|
||||
f64_from_bits(0x7FF0000000000000)
|
||||
}
|
||||
|
||||
pub fn f64_get_neg_inf() -> f64 {
|
||||
f64_from_bits(0xFFF0000000000000)
|
||||
}
|
||||
|
||||
pub fn f64_is_nan(f: f64) -> bool {
|
||||
const bits = f64_to_bits(f);
|
||||
const exp: i64 = i64((bits >> 52) & ((1 << 11) - 1));
|
||||
const sig = (bits & ((1 << 52) - 1)) | (1 << 52);
|
||||
|
||||
sig != 0 && exp == (1 << 11) - 1
|
||||
}
|
||||
|
||||
pub fn f64_is_inf(f: f64) -> bool {
|
||||
f == f64_get_neg_inf() || f == f64_get_pos_inf()
|
||||
}
|
||||
|
||||
pub fn min(inline T: type, x: T, y: T) -> T {
|
||||
if (x < y) x else y
|
||||
}
|
||||
@ -41,15 +13,15 @@ pub fn max(inline T: type, x: T, y: T) -> T {
|
||||
}
|
||||
|
||||
pub error Overflow;
|
||||
pub fn mul_overflow(inline T: type, a: T, b: T) -> %T {
|
||||
pub fn mulOverflow(inline T: type, a: T, b: T) -> %T {
|
||||
var answer: T = undefined;
|
||||
if (@mul_with_overflow(T, a, b, &answer)) error.Overflow else answer
|
||||
if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||
}
|
||||
pub fn add_overflow(inline T: type, a: T, b: T) -> %T {
|
||||
pub fn addOverflow(inline T: type, a: T, b: T) -> %T {
|
||||
var answer: T = undefined;
|
||||
if (@add_with_overflow(T, a, b, &answer)) error.Overflow else answer
|
||||
if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||
}
|
||||
pub fn sub_overflow(inline T: type, a: T, b: T) -> %T {
|
||||
pub fn subOverflow(inline T: type, a: T, b: T) -> %T {
|
||||
var answer: T = undefined;
|
||||
if (@sub_with_overflow(T, a, b, &answer)) error.Overflow else answer
|
||||
if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||
}
|
||||
|
22
std/mem.zig
22
std/mem.zig
@ -9,34 +9,34 @@ pub error NoMem;
|
||||
|
||||
pub type Context = u8;
|
||||
pub struct Allocator {
|
||||
alloc_fn: fn (self: &Allocator, n: usize) -> %[]u8,
|
||||
realloc_fn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8,
|
||||
free_fn: fn (self: &Allocator, mem: []u8),
|
||||
allocFn: fn (self: &Allocator, n: usize) -> %[]u8,
|
||||
reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8,
|
||||
freeFn: fn (self: &Allocator, mem: []u8),
|
||||
context: ?&Context,
|
||||
|
||||
/// Aborts the program if an allocation fails.
|
||||
fn checked_alloc(self: &Allocator, inline T: type, n: usize) -> []T {
|
||||
fn checkedAlloc(self: &Allocator, inline T: type, n: usize) -> []T {
|
||||
alloc(self, T, n) %% |err| {
|
||||
// TODO var args printf
|
||||
%%io.stderr.write("allocation failure: ");
|
||||
%%io.stderr.write(@err_name(err));
|
||||
%%io.stderr.write(@errName(err));
|
||||
%%io.stderr.printf("\n");
|
||||
os.abort()
|
||||
}
|
||||
}
|
||||
|
||||
fn alloc(self: &Allocator, inline T: type, n: usize) -> %[]T {
|
||||
const byte_count = %return math.mul_overflow(usize, @sizeof(T), n);
|
||||
([]T)(%return self.alloc_fn(self, byte_count))
|
||||
const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
|
||||
([]T)(%return self.allocFn(self, byte_count))
|
||||
}
|
||||
|
||||
fn realloc(self: &Allocator, inline T: type, old_mem: []T, n: usize) -> %[]T {
|
||||
const byte_count = %return math.mul_overflow(usize, @sizeof(T), n);
|
||||
([]T)(%return self.realloc_fn(self, ([]u8)(old_mem), byte_count))
|
||||
const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
|
||||
([]T)(%return self.reallocFn(self, ([]u8)(old_mem), byte_count))
|
||||
}
|
||||
|
||||
fn free(self: &Allocator, inline T: type, mem: []T) {
|
||||
self.free_fn(self, ([]u8)(mem));
|
||||
self.freeFn(self, ([]u8)(mem));
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ pub struct Allocator {
|
||||
/// dest.len must be >= source.len.
|
||||
pub fn copy(inline T: type, dest: []T, source: []const T) {
|
||||
assert(dest.len >= source.len);
|
||||
@memcpy(dest.ptr, source.ptr, @sizeof(T) * source.len);
|
||||
@memcpy(dest.ptr, source.ptr, @sizeOf(T) * source.len);
|
||||
}
|
||||
|
||||
/// Return < 0, == 0, or > 0 if memory a is less than, equal to, or greater than,
|
||||
|
86
std/net.zig
86
std/net.zig
@ -17,7 +17,7 @@ struct Connection {
|
||||
|
||||
pub fn send(c: Connection, buf: []const u8) -> %usize {
|
||||
const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
|
||||
const send_err = linux.get_errno(send_ret);
|
||||
const send_err = linux.getErrno(send_ret);
|
||||
switch (send_err) {
|
||||
0 => return send_ret,
|
||||
errno.EINVAL => unreachable{},
|
||||
@ -31,7 +31,7 @@ struct Connection {
|
||||
|
||||
pub fn recv(c: Connection, buf: []u8) -> %[]u8 {
|
||||
const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
|
||||
const recv_err = linux.get_errno(recv_ret);
|
||||
const recv_err = linux.getErrno(recv_ret);
|
||||
switch (recv_err) {
|
||||
0 => return buf[0...recv_ret],
|
||||
errno.EINVAL => unreachable{},
|
||||
@ -47,7 +47,7 @@ struct Connection {
|
||||
}
|
||||
|
||||
pub fn close(c: Connection) -> %void {
|
||||
switch (linux.get_errno(linux.close(c.socket_fd))) {
|
||||
switch (linux.getErrno(linux.close(c.socket_fd))) {
|
||||
0 => return,
|
||||
errno.EBADF => unreachable{},
|
||||
errno.EINTR => return error.SigInterrupt,
|
||||
@ -76,7 +76,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
|
||||
unreachable{} // TODO
|
||||
}
|
||||
|
||||
switch (parse_ip_literal(hostname)) {
|
||||
switch (parseIpLiteral(hostname)) {
|
||||
Ok => |addr| {
|
||||
out_addrs[0] = addr;
|
||||
return out_addrs[0...1];
|
||||
@ -87,9 +87,9 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
|
||||
unreachable{} // TODO
|
||||
}
|
||||
|
||||
pub fn connect_addr(addr: &Address, port: u16) -> %Connection {
|
||||
pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
|
||||
const socket_ret = linux.socket(addr.family, linux.SOCK_STREAM, linux.PROTO_tcp);
|
||||
const socket_err = linux.get_errno(socket_ret);
|
||||
const socket_err = linux.getErrno(socket_ret);
|
||||
if (socket_err > 0) {
|
||||
// TODO figure out possible errors from socket()
|
||||
return error.Unexpected;
|
||||
@ -99,22 +99,22 @@ pub fn connect_addr(addr: &Address, port: u16) -> %Connection {
|
||||
const connect_ret = if (addr.family == linux.AF_INET) {
|
||||
var os_addr: linux.sockaddr_in = undefined;
|
||||
os_addr.family = addr.family;
|
||||
os_addr.port = swap_if_little_endian(u16, port);
|
||||
os_addr.port = swapIfLittleEndian(u16, port);
|
||||
@memcpy((&u8)(&os_addr.addr), &addr.addr[0], 4);
|
||||
@memset(&os_addr.zero, 0, @sizeof(@typeof(os_addr.zero)));
|
||||
linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeof(linux.sockaddr_in))
|
||||
@memset(&os_addr.zero, 0, @sizeOf(@typeOf(os_addr.zero)));
|
||||
linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeOf(linux.sockaddr_in))
|
||||
} else if (addr.family == linux.AF_INET6) {
|
||||
var os_addr: linux.sockaddr_in6 = undefined;
|
||||
os_addr.family = addr.family;
|
||||
os_addr.port = swap_if_little_endian(u16, port);
|
||||
os_addr.port = swapIfLittleEndian(u16, port);
|
||||
os_addr.flowinfo = 0;
|
||||
os_addr.scope_id = addr.scope_id;
|
||||
@memcpy(&os_addr.addr[0], &addr.addr[0], 16);
|
||||
linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeof(linux.sockaddr_in6))
|
||||
linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeOf(linux.sockaddr_in6))
|
||||
} else {
|
||||
unreachable{}
|
||||
};
|
||||
const connect_err = linux.get_errno(connect_ret);
|
||||
const connect_err = linux.getErrno(connect_ret);
|
||||
if (connect_err > 0) {
|
||||
switch (connect_err) {
|
||||
errno.ETIMEDOUT => return error.TimedOut,
|
||||
@ -135,23 +135,23 @@ pub fn connect(hostname: []const u8, port: u16) -> %Connection {
|
||||
const addrs_slice = %return lookup(hostname, addrs_buf);
|
||||
const main_addr = &addrs_slice[0];
|
||||
|
||||
return connect_addr(main_addr, port);
|
||||
return connectAddr(main_addr, port);
|
||||
}
|
||||
|
||||
pub error InvalidIpLiteral;
|
||||
|
||||
pub fn parse_ip_literal(buf: []const u8) -> %Address {
|
||||
switch (parse_ip4(buf)) {
|
||||
pub fn parseIpLiteral(buf: []const u8) -> %Address {
|
||||
switch (parseIp4(buf)) {
|
||||
Ok => |ip4| {
|
||||
var result: Address = undefined;
|
||||
@memcpy(&result.addr[0], (&u8)(&ip4), @sizeof(u32));
|
||||
@memcpy(&result.addr[0], (&u8)(&ip4), @sizeOf(u32));
|
||||
result.family = linux.AF_INET;
|
||||
result.scope_id = 0;
|
||||
return result;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
switch (parse_ip6(buf)) {
|
||||
switch (parseIp6(buf)) {
|
||||
Ok => |addr| {
|
||||
return addr;
|
||||
},
|
||||
@ -161,7 +161,7 @@ pub fn parse_ip_literal(buf: []const u8) -> %Address {
|
||||
return error.InvalidIpLiteral;
|
||||
}
|
||||
|
||||
fn hex_digit(c: u8) -> u8 {
|
||||
fn hexDigit(c: u8) -> u8 {
|
||||
// TODO use switch with range
|
||||
if ('0' <= c && c <= '9') {
|
||||
c - '0'
|
||||
@ -170,7 +170,7 @@ fn hex_digit(c: u8) -> u8 {
|
||||
} else if ('a' <= c && c <= 'z') {
|
||||
c - 'a' + 10
|
||||
} else {
|
||||
@max_value(u8)
|
||||
@maxValue(u8)
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ error JunkAtEnd;
|
||||
error Incomplete;
|
||||
|
||||
#static_eval_enable(false)
|
||||
fn parse_ip6(buf: []const u8) -> %Address {
|
||||
fn parseIp6(buf: []const u8) -> %Address {
|
||||
var result: Address = undefined;
|
||||
result.family = linux.AF_INET6;
|
||||
result.scope_id = 0;
|
||||
@ -194,10 +194,10 @@ fn parse_ip6(buf: []const u8) -> %Address {
|
||||
if (scope_id) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
const digit = c - '0';
|
||||
if (@mul_with_overflow(u32, result.scope_id, 10, &result.scope_id)) {
|
||||
if (@mulWithOverflow(u32, result.scope_id, 10, &result.scope_id)) {
|
||||
return error.Overflow;
|
||||
}
|
||||
if (@add_with_overflow(u32, result.scope_id, digit, &result.scope_id)) {
|
||||
if (@addWithOverflow(u32, result.scope_id, digit, &result.scope_id)) {
|
||||
return error.Overflow;
|
||||
}
|
||||
} else {
|
||||
@ -230,14 +230,14 @@ fn parse_ip6(buf: []const u8) -> %Address {
|
||||
scope_id = true;
|
||||
saw_any_digits = false;
|
||||
} else {
|
||||
const digit = hex_digit(c);
|
||||
if (digit == @max_value(u8)) {
|
||||
const digit = hexDigit(c);
|
||||
if (digit == @maxValue(u8)) {
|
||||
return error.InvalidChar;
|
||||
}
|
||||
if (@mul_with_overflow(u16, x, 16, &x)) {
|
||||
if (@mulWithOverflow(u16, x, 16, &x)) {
|
||||
return error.Overflow;
|
||||
}
|
||||
if (@add_with_overflow(u16, x, digit, &x)) {
|
||||
if (@addWithOverflow(u16, x, digit, &x)) {
|
||||
return error.Overflow;
|
||||
}
|
||||
saw_any_digits = true;
|
||||
@ -276,7 +276,7 @@ fn parse_ip6(buf: []const u8) -> %Address {
|
||||
return error.Incomplete;
|
||||
}
|
||||
|
||||
fn parse_ip4(buf: []const u8) -> %u32 {
|
||||
fn parseIp4(buf: []const u8) -> %u32 {
|
||||
var result: u32 = undefined;
|
||||
const out_ptr = ([]u8)((&result)[0...1]);
|
||||
|
||||
@ -298,10 +298,10 @@ fn parse_ip4(buf: []const u8) -> %u32 {
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
saw_any_digits = true;
|
||||
const digit = c - '0';
|
||||
if (@mul_with_overflow(u8, x, 10, &x)) {
|
||||
if (@mulWithOverflow(u8, x, 10, &x)) {
|
||||
return error.Overflow;
|
||||
}
|
||||
if (@add_with_overflow(u8, x, digit, &x)) {
|
||||
if (@addWithOverflow(u8, x, digit, &x)) {
|
||||
return error.Overflow;
|
||||
}
|
||||
} else {
|
||||
@ -318,19 +318,19 @@ fn parse_ip4(buf: []const u8) -> %u32 {
|
||||
|
||||
|
||||
#attribute("test")
|
||||
fn test_parse_ip4() {
|
||||
assert(%%parse_ip4("127.0.0.1") == swap_if_little_endian(u32, 0x7f000001));
|
||||
switch (parse_ip4("256.0.0.1")) { Overflow => {}, else => unreachable {}, }
|
||||
switch (parse_ip4("x.0.0.1")) { InvalidChar => {}, else => unreachable {}, }
|
||||
switch (parse_ip4("127.0.0.1.1")) { JunkAtEnd => {}, else => unreachable {}, }
|
||||
switch (parse_ip4("127.0.0.")) { Incomplete => {}, else => unreachable {}, }
|
||||
switch (parse_ip4("100..0.1")) { InvalidChar => {}, else => unreachable {}, }
|
||||
fn testParseIp4() {
|
||||
assert(%%parseIp4("127.0.0.1") == swapIfLittleEndian(u32, 0x7f000001));
|
||||
switch (parseIp4("256.0.0.1")) { Overflow => {}, else => unreachable {}, }
|
||||
switch (parseIp4("x.0.0.1")) { InvalidChar => {}, else => unreachable {}, }
|
||||
switch (parseIp4("127.0.0.1.1")) { JunkAtEnd => {}, else => unreachable {}, }
|
||||
switch (parseIp4("127.0.0.")) { Incomplete => {}, else => unreachable {}, }
|
||||
switch (parseIp4("100..0.1")) { InvalidChar => {}, else => unreachable {}, }
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn test_parse_ip6() {
|
||||
fn testParseIp6() {
|
||||
{
|
||||
const addr = %%parse_ip6("FF01:0:0:0:0:0:0:FB");
|
||||
const addr = %%parseIp6("FF01:0:0:0:0:0:0:FB");
|
||||
assert(addr.addr[0] == 0xff);
|
||||
assert(addr.addr[1] == 0x01);
|
||||
assert(addr.addr[2] == 0x00);
|
||||
@ -338,7 +338,7 @@ fn test_parse_ip6() {
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn test_lookup_simple_ip() {
|
||||
fn testLookupSimpleIp() {
|
||||
{
|
||||
var addrs_buf: [5]Address = undefined;
|
||||
const addrs = %%lookup("192.168.1.1", addrs_buf);
|
||||
@ -352,16 +352,16 @@ fn test_lookup_simple_ip() {
|
||||
}
|
||||
}
|
||||
|
||||
fn swap_if_little_endian(inline T: type, x: T) -> T {
|
||||
if (@compile_var("is_big_endian")) x else endian_swap(T, x)
|
||||
fn swapIfLittleEndian(inline T: type, x: T) -> T {
|
||||
if (@compileVar("is_big_endian")) x else endianSwap(T, x)
|
||||
}
|
||||
|
||||
fn endian_swap(inline T: type, x: T) -> T {
|
||||
fn endianSwap(inline T: type, x: T) -> T {
|
||||
const x_slice = ([]u8)((&const x)[0...1]);
|
||||
var result: T = undefined;
|
||||
const result_slice = ([]u8)((&result)[0...1]);
|
||||
for (result_slice) |*b, i| {
|
||||
*b = x_slice[@sizeof(T) - i - 1];
|
||||
*b = x_slice[@sizeOf(T) - i - 1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ pub error SigInterrupt;
|
||||
pub error Unexpected;
|
||||
|
||||
pub fn get_random_bytes(buf: []u8) -> %void {
|
||||
switch (@compile_var("os")) {
|
||||
switch (@compileVar("os")) {
|
||||
linux => {
|
||||
const ret = linux.getrandom(buf.ptr, buf.len, 0);
|
||||
const err = linux.get_errno(ret);
|
||||
const err = linux.getErrno(ret);
|
||||
if (err > 0) {
|
||||
return switch (err) {
|
||||
errno.EINVAL => unreachable{},
|
||||
|
60
std/rand.zig
60
std/rand.zig
@ -19,15 +19,13 @@ pub const MT19937_64 = MersenneTwister(
|
||||
|
||||
/// Use `init` to initialize this state.
|
||||
pub struct Rand {
|
||||
const Rng = if (@sizeof(usize) >= 8) MT19937_64 else MT19937_32;
|
||||
const Rng = if (@sizeOf(usize) >= 8) MT19937_64 else MT19937_32;
|
||||
|
||||
rng: Rng,
|
||||
|
||||
/// Initialize random state with the given seed.
|
||||
pub fn init(seed: usize) -> Rand {
|
||||
var r: Rand = undefined;
|
||||
r.rng = Rng.init(seed);
|
||||
return r;
|
||||
pub fn init(r: &Rand, seed: usize) {
|
||||
r.rng.init(seed);
|
||||
}
|
||||
|
||||
/// Get an integer with random bits.
|
||||
@ -35,24 +33,24 @@ pub struct Rand {
|
||||
if (T == usize) {
|
||||
return r.rng.get();
|
||||
} else {
|
||||
var result: [@sizeof(T)]u8 = undefined;
|
||||
r.fill_bytes(result);
|
||||
var result: [@sizeOf(T)]u8 = undefined;
|
||||
r.fillBytes(result);
|
||||
return ([]T)(result)[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill `buf` with randomness.
|
||||
pub fn fill_bytes(r: &Rand, buf: []u8) {
|
||||
pub fn fillBytes(r: &Rand, buf: []u8) {
|
||||
var bytes_left = buf.len;
|
||||
while (bytes_left >= @sizeof(usize)) {
|
||||
while (bytes_left >= @sizeOf(usize)) {
|
||||
([]usize)(buf[buf.len - bytes_left...])[0] = r.rng.get();
|
||||
bytes_left -= @sizeof(usize);
|
||||
bytes_left -= @sizeOf(usize);
|
||||
}
|
||||
if (bytes_left > 0) {
|
||||
var rand_val_array : [@sizeof(usize)]u8 = undefined;
|
||||
var rand_val_array : [@sizeOf(usize)]u8 = undefined;
|
||||
([]usize)(rand_val_array)[0] = r.rng.get();
|
||||
while (bytes_left > 0) {
|
||||
buf[buf.len - bytes_left] = rand_val_array[@sizeof(usize) - bytes_left];
|
||||
buf[buf.len - bytes_left] = rand_val_array[@sizeOf(usize) - bytes_left];
|
||||
bytes_left -= 1;
|
||||
}
|
||||
}
|
||||
@ -61,14 +59,14 @@ pub struct Rand {
|
||||
/// Get a random unsigned integer with even distribution between `start`
|
||||
/// inclusive and `end` exclusive.
|
||||
// TODO support signed integers and then rename to "range"
|
||||
pub fn range_unsigned(r: &Rand, inline T: type, start: T, end: T) -> T {
|
||||
pub fn rangeUnsigned(r: &Rand, inline T: type, start: T, end: T) -> T {
|
||||
const range = end - start;
|
||||
const leftover = @max_value(T) % range;
|
||||
const upper_bound = @max_value(T) - leftover;
|
||||
var rand_val_array : [@sizeof(T)]u8 = undefined;
|
||||
const leftover = @maxValue(T) % range;
|
||||
const upper_bound = @maxValue(T) - leftover;
|
||||
var rand_val_array : [@sizeOf(T)]u8 = undefined;
|
||||
|
||||
while (true) {
|
||||
r.fill_bytes(rand_val_array);
|
||||
r.fillBytes(rand_val_array);
|
||||
const rand_val = ([]T)(rand_val_array)[0];
|
||||
if (rand_val < upper_bound) {
|
||||
return start + (rand_val % range);
|
||||
@ -79,19 +77,19 @@ pub struct Rand {
|
||||
/// Get a floating point value in the range 0.0..1.0.
|
||||
pub fn float(r: &Rand, inline T: type) -> T {
|
||||
// TODO Implement this way instead:
|
||||
// const int = @int_type(false, @sizeof(T) * 8);
|
||||
// const int = @int_type(false, @sizeOf(T) * 8);
|
||||
// const mask = ((1 << @float_mantissa_bit_count(T)) - 1);
|
||||
// const rand_bits = r.rng.scalar(int) & mask;
|
||||
// return @float_compose(T, false, 0, rand_bits) - 1.0
|
||||
const int_type = @int_type(false, @sizeof(T) * 8);
|
||||
const int_type = @intType(false, @sizeOf(T) * 8);
|
||||
const precision = if (T == f32) {
|
||||
16777216
|
||||
} else if (T == f64) {
|
||||
9007199254740992
|
||||
} else {
|
||||
@compile_err("unknown floating point type" ++ @type_name(T))
|
||||
@compile_err("unknown floating point type" ++ @typeName(T))
|
||||
};
|
||||
return T(r.range_unsigned(int_type, 0, precision)) / T(precision);
|
||||
return T(r.rangeUnsigned(int_type, 0, precision)) / T(precision);
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,8 +108,7 @@ struct MersenneTwister(
|
||||
|
||||
// TODO improve compile time eval code and then allow this function to be executed at compile time.
|
||||
#static_eval_enable(false)
|
||||
pub fn init(seed: int) -> Self {
|
||||
var mt: Self = undefined;
|
||||
pub fn init(mt: &Self, seed: int) {
|
||||
mt.index = n;
|
||||
|
||||
var prev_value = seed;
|
||||
@ -120,8 +117,6 @@ struct MersenneTwister(
|
||||
prev_value = int(i) +% f *% (prev_value ^ (prev_value >> (int.bit_count - 2)));
|
||||
mt.array[i] = prev_value;
|
||||
}};
|
||||
|
||||
return mt;
|
||||
}
|
||||
|
||||
pub fn get(mt: &Self) -> int {
|
||||
@ -161,8 +156,9 @@ struct MersenneTwister(
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn test_float32() {
|
||||
var r = Rand.init(42);
|
||||
fn testFloat32() {
|
||||
var r: Rand = undefined;
|
||||
r.init(42);
|
||||
|
||||
{var i: usize = 0; while (i < 1000; i += 1) {
|
||||
const val = r.float(f32);
|
||||
@ -172,16 +168,18 @@ fn test_float32() {
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn test_MT19937_64() {
|
||||
const rng = MT19937_64.init(rand_test.mt64_seed);
|
||||
fn testMT19937_64() {
|
||||
var rng: MT19937_64 = undefined;
|
||||
rng.init(rand_test.mt64_seed);
|
||||
for (rand_test.mt64_data) |value| {
|
||||
assert(value == rng.get());
|
||||
}
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn test_MT19937_32() {
|
||||
const rng = MT19937_32.init(rand_test.mt32_seed);
|
||||
fn testMT19937_32() {
|
||||
var rng: MT19937_32 = undefined;
|
||||
rng.init(rand_test.mt32_seed);
|
||||
for (rand_test.mt32_data) |value| {
|
||||
assert(value == rng.get());
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
const assert = @import("debug.zig").assert;
|
||||
|
||||
pub fn eql(a: []const u8, b: []const u8) -> bool {
|
||||
slice_eql(u8, a, b)
|
||||
sliceEql(u8, a, b)
|
||||
}
|
||||
|
||||
pub fn slice_eql(inline T: type, a: []const T, b: []const T) -> bool {
|
||||
pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool {
|
||||
if (a.len != b.len) return false;
|
||||
for (a) |item, index| {
|
||||
if (b[index] != item) return false;
|
||||
@ -13,7 +13,7 @@ pub fn slice_eql(inline T: type, a: []const T, b: []const T) -> bool {
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn string_equality() {
|
||||
fn stringEquality() {
|
||||
assert(eql("abcd", "abcd"));
|
||||
assert(!eql("abcdef", "abZdef"));
|
||||
assert(!eql("abcdefg", "abcdef"));
|
||||
|
@ -7,19 +7,19 @@ struct TestFn {
|
||||
|
||||
extern var zig_test_fn_list: []TestFn;
|
||||
|
||||
pub fn run_tests() -> %void {
|
||||
for (zig_test_fn_list) |test_fn, i| {
|
||||
pub fn runTests() -> %void {
|
||||
for (zig_test_fn_list) |testFn, i| {
|
||||
// TODO: print var args
|
||||
%%io.stderr.write("Test ");
|
||||
%%io.stderr.print_u64(i + 1);
|
||||
%%io.stderr.write("/");
|
||||
%%io.stderr.print_u64(zig_test_fn_list.len);
|
||||
%%io.stderr.write(" ");
|
||||
%%io.stderr.write(test_fn.name);
|
||||
%%io.stderr.write(testFn.name);
|
||||
%%io.stderr.write("...");
|
||||
%%io.stderr.flush();
|
||||
|
||||
test_fn.func();
|
||||
testFn.func();
|
||||
|
||||
|
||||
%%io.stderr.write("OK\n");
|
||||
|
@ -1,6 +1,6 @@
|
||||
const test_runner = @import("test_runner.zig");
|
||||
|
||||
export fn main(argc: c_int, argv: &&u8) -> c_int {
|
||||
test_runner.run_tests() %% return -1;
|
||||
test_runner.runTests() %% return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
const test_runner = @import("test_runner.zig");
|
||||
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
return test_runner.run_tests();
|
||||
return test_runner.runTests();
|
||||
}
|
||||
|
9
test/cases/sizeof_and_typeof.zig
Normal file
9
test/cases/sizeof_and_typeof.zig
Normal file
@ -0,0 +1,9 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
#attribute("test")
|
||||
fn sizeofAndTypeOf() {
|
||||
const y: @typeOf(x) = 120;
|
||||
assert(@sizeOf(@typeOf(y)) == 2);
|
||||
}
|
||||
const x: u16 = 13;
|
||||
const z: @typeOf(x) = 19;
|
@ -202,7 +202,7 @@ static TestCase *add_parseh_case(const char *case_name, const char *source, int
|
||||
|
||||
static void add_compiling_test_cases(void) {
|
||||
add_simple_case_libc("hello world with libc", R"SOURCE(
|
||||
const c = @c_import(@c_include("stdio.h"));
|
||||
const c = @cImport(@cInclude("stdio.h"));
|
||||
export fn main(argc: c_int, argv: &&u8) -> c_int {
|
||||
c.puts(c"Hello, world!");
|
||||
return 0;
|
||||
@ -215,12 +215,12 @@ use @import("std").io;
|
||||
use @import("foo.zig");
|
||||
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
private_function();
|
||||
privateFunction();
|
||||
%%stdout.printf("OK 2\n");
|
||||
}
|
||||
|
||||
fn private_function() {
|
||||
print_text();
|
||||
fn privateFunction() {
|
||||
printText();
|
||||
}
|
||||
)SOURCE", "OK 1\nOK 2\n");
|
||||
|
||||
@ -229,12 +229,12 @@ use @import("std").io;
|
||||
|
||||
// purposefully conflicting function with main.zig
|
||||
// but it's private so it should be OK
|
||||
fn private_function() {
|
||||
fn privateFunction() {
|
||||
%%stdout.printf("OK 1\n");
|
||||
}
|
||||
|
||||
pub fn print_text() {
|
||||
private_function();
|
||||
pub fn printText() {
|
||||
privateFunction();
|
||||
}
|
||||
)SOURCE");
|
||||
}
|
||||
@ -316,7 +316,7 @@ pub fn main(args: [][]u8) -> %void {
|
||||
|
||||
|
||||
add_simple_case_libc("number literals", R"SOURCE(
|
||||
const c = @c_import(@c_include("stdio.h"));
|
||||
const c = @cImport(@cInclude("stdio.h"));
|
||||
|
||||
export fn main(argc: c_int, argv: &&u8) -> c_int {
|
||||
c.printf(c"\n");
|
||||
@ -444,12 +444,12 @@ export fn main(argc: c_int, argv: &&u8) -> c_int {
|
||||
add_simple_case("order-independent declarations", R"SOURCE(
|
||||
const io = @import("std").io;
|
||||
const z = io.stdin_fileno;
|
||||
const x : @typeof(y) = 1234;
|
||||
const x : @typeOf(y) = 1234;
|
||||
const y : u16 = 5678;
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
var x_local : i32 = print_ok(x);
|
||||
}
|
||||
fn print_ok(val: @typeof(x)) -> @typeof(foo) {
|
||||
fn print_ok(val: @typeOf(x)) -> @typeOf(foo) {
|
||||
%%io.stdout.printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
@ -482,7 +482,7 @@ pub fn main(args: [][]u8) -> %void {
|
||||
)SOURCE", "9\n8\n7\n6\n0\n1\n2\n3\n9\n8\n7\n6\n0\n1\n2\n3\n");
|
||||
|
||||
add_simple_case_libc("expose function pointer to C land", R"SOURCE(
|
||||
const c = @c_import(@c_include("stdlib.h"));
|
||||
const c = @cImport(@cInclude("stdlib.h"));
|
||||
|
||||
export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
|
||||
const a_int = (&i32)(a ?? unreachable{});
|
||||
@ -499,7 +499,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
|
||||
export fn main(args: c_int, argv: &&u8) -> c_int {
|
||||
var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
|
||||
|
||||
c.qsort((&c_void)(&array[0]), c_ulong(array.len), @sizeof(i32), compare_fn);
|
||||
c.qsort((&c_void)(&array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
|
||||
|
||||
for (array) |item, i| {
|
||||
if (item != i) {
|
||||
@ -514,7 +514,7 @@ export fn main(args: c_int, argv: &&u8) -> c_int {
|
||||
|
||||
|
||||
add_simple_case_libc("casting between float and integer types", R"SOURCE(
|
||||
const c = @c_import(@c_include("stdio.h"));
|
||||
const c = @cImport(@cInclude("stdio.h"));
|
||||
export fn main(argc: c_int, argv: &&u8) -> c_int {
|
||||
const small: f32 = 3.25;
|
||||
const x: f64 = small;
|
||||
@ -654,8 +654,8 @@ fn its_gonna_pass() -> %void { }
|
||||
|
||||
|
||||
{
|
||||
TestCase *tc = add_simple_case("@embed_file", R"SOURCE(
|
||||
const foo_txt = @embed_file("foo.txt");
|
||||
TestCase *tc = add_simple_case("@embedFile", R"SOURCE(
|
||||
const foo_txt = @embedFile("foo.txt");
|
||||
const io = @import("std").io;
|
||||
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
@ -956,8 +956,8 @@ fn f() -> @bogus(foo) {
|
||||
)SOURCE", 1, ".tmp_source.zig:2:11: error: invalid builtin function: 'bogus'");
|
||||
|
||||
add_compile_fail_case("top level decl dependency loop", R"SOURCE(
|
||||
const a : @typeof(b) = 0;
|
||||
const b : @typeof(a) = 0;
|
||||
const a : @typeOf(b) = 0;
|
||||
const b : @typeOf(a) = 0;
|
||||
)SOURCE", 1, ".tmp_source.zig:2:1: error: 'a' depends on itself");
|
||||
|
||||
add_compile_fail_case("noalias on non pointer param", R"SOURCE(
|
||||
@ -1012,8 +1012,8 @@ fn f(s: [10]u8) -> []u8 {
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: array concatenation requires constant expression");
|
||||
|
||||
add_compile_fail_case("c_import with bogus include", R"SOURCE(
|
||||
const c = @c_import(@c_include("bogus.h"));
|
||||
add_compile_fail_case("@cImport with bogus include", R"SOURCE(
|
||||
const c = @cImport(@cInclude("bogus.h"));
|
||||
)SOURCE", 2, ".tmp_source.zig:2:11: error: C import failed",
|
||||
".h:1:10: note: 'bogus.h' file not found");
|
||||
|
||||
@ -1022,12 +1022,12 @@ const x = 3;
|
||||
const y = &x;
|
||||
)SOURCE", 1, ".tmp_source.zig:3:12: error: unable to get address of type '(integer literal)'");
|
||||
|
||||
add_compile_fail_case("@typeof number literal", R"SOURCE(
|
||||
add_compile_fail_case("@typeOf number literal", R"SOURCE(
|
||||
const x = 3;
|
||||
struct Foo {
|
||||
index: @typeof(x),
|
||||
index: @typeOf(x),
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:20: error: type '(integer literal)' not eligible for @typeof");
|
||||
)SOURCE", 1, ".tmp_source.zig:4:20: error: type '(integer literal)' not eligible for @typeOf");
|
||||
|
||||
add_compile_fail_case("integer overflow error", R"SOURCE(
|
||||
const x : u8 = 300;
|
||||
@ -1050,7 +1050,7 @@ struct Foo {
|
||||
}
|
||||
}
|
||||
|
||||
const member_fn_type = @typeof(Foo.member_a);
|
||||
const member_fn_type = @typeOf(Foo.member_a);
|
||||
const members = []member_fn_type {
|
||||
Foo.member_a,
|
||||
Foo.member_b,
|
||||
@ -1101,15 +1101,15 @@ fn func() -> bogus {}
|
||||
|
||||
|
||||
add_compile_fail_case("bogus compile var", R"SOURCE(
|
||||
const x = @compile_var("bogus");
|
||||
)SOURCE", 1, ".tmp_source.zig:2:24: error: unrecognized compile variable: 'bogus'");
|
||||
const x = @compileVar("bogus");
|
||||
)SOURCE", 1, ".tmp_source.zig:2:23: error: unrecognized compile variable: 'bogus'");
|
||||
|
||||
|
||||
add_compile_fail_case("@const_eval", R"SOURCE(
|
||||
add_compile_fail_case("@constEval", R"SOURCE(
|
||||
fn a(x: i32) {
|
||||
const y = @const_eval(x);
|
||||
const y = @constEval(x);
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:27: error: unable to evaluate constant expression");
|
||||
)SOURCE", 1, ".tmp_source.zig:3:26: error: unable to evaluate constant expression");
|
||||
|
||||
add_compile_fail_case("non constant expression in array size outside function", R"SOURCE(
|
||||
struct Foo {
|
||||
@ -1245,8 +1245,8 @@ fn fibbonaci(x: i32) -> i32 {
|
||||
".tmp_source.zig:2:37: note: called from here",
|
||||
".tmp_source.zig:4:40: note: quota exceeded here");
|
||||
|
||||
add_compile_fail_case("@embed_file with bogus file", R"SOURCE(
|
||||
const resource = @embed_file("bogus.txt");
|
||||
add_compile_fail_case("@embedFile with bogus file", R"SOURCE(
|
||||
const resource = @embedFile("bogus.txt");
|
||||
)SOURCE", 1, ".tmp_source.zig:2:18: error: unable to find './bogus.txt'");
|
||||
|
||||
|
||||
@ -1555,23 +1555,23 @@ fn div0(a: i32, b: i32) -> i32 {
|
||||
add_debug_safety_case("exact division failure", R"SOURCE(
|
||||
error Whatever;
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
const x = div_exact(10, 3);
|
||||
const x = divExact(10, 3);
|
||||
if (x == 0) return error.Whatever;
|
||||
}
|
||||
#static_eval_enable(false)
|
||||
fn div_exact(a: i32, b: i32) -> i32 {
|
||||
@div_exact(a, b)
|
||||
fn divExact(a: i32, b: i32) -> i32 {
|
||||
@divExact(a, b)
|
||||
}
|
||||
)SOURCE");
|
||||
|
||||
add_debug_safety_case("cast []u8 to bigger slice of wrong size", R"SOURCE(
|
||||
error Whatever;
|
||||
pub fn main(args: [][]u8) -> %void {
|
||||
const x = widen_slice([]u8{1, 2, 3, 4, 5});
|
||||
const x = widenSlice([]u8{1, 2, 3, 4, 5});
|
||||
if (x.len == 0) return error.Whatever;
|
||||
}
|
||||
#static_eval_enable(false)
|
||||
fn widen_slice(slice: []u8) -> []i32 {
|
||||
fn widenSlice(slice: []u8) -> []i32 {
|
||||
([]i32)(slice)
|
||||
}
|
||||
)SOURCE");
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user