parent
6a5e61acd1
commit
47cf8520ad
@ -15,7 +15,7 @@ ErrorValueDecl = "error" Symbol ";"
|
|||||||
|
|
||||||
GlobalVarDecl = VariableDeclaration ";"
|
GlobalVarDecl = VariableDeclaration ";"
|
||||||
|
|
||||||
VariableDeclaration = option("inline") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
|
VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
|
||||||
|
|
||||||
StructMember = (StructField | FnDef | GlobalVarDecl)
|
StructMember = (StructField | FnDef | GlobalVarDecl)
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ FnDef = option("inline" | "extern") FnProto Block
|
|||||||
|
|
||||||
ParamDeclList = "(" list(ParamDecl, ",") ")"
|
ParamDeclList = "(" list(ParamDecl, ",") ")"
|
||||||
|
|
||||||
ParamDecl = option("noalias" | "inline") option(Symbol ":") TypeExpr | "..."
|
ParamDecl = option("noalias" | "comptime") option(Symbol ":") TypeExpr | "..."
|
||||||
|
|
||||||
Block = "{" list(option(Statement), ";") "}"
|
Block = "{" list(option(Statement), ";") "}"
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ if exists("b:current_syntax")
|
|||||||
endif
|
endif
|
||||||
let b:current_syntax = "zig"
|
let b:current_syntax = "zig"
|
||||||
|
|
||||||
syn keyword zigStorage const var extern export pub noalias inline nakedcc coldcc
|
syn keyword zigStorage const var extern export pub noalias inline comptime nakedcc coldcc
|
||||||
syn keyword zigStructure struct enum union
|
syn keyword zigStructure struct enum union
|
||||||
syn keyword zigStatement goto break return continue asm defer
|
syn keyword zigStatement goto break return continue asm defer
|
||||||
syn keyword zigConditional if else switch
|
syn keyword zigConditional if else switch
|
||||||
|
@ -979,7 +979,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
|
|||||||
if (param_is_inline) {
|
if (param_is_inline) {
|
||||||
if (fn_type_id.is_extern) {
|
if (fn_type_id.is_extern) {
|
||||||
add_node_error(g, param_node,
|
add_node_error(g, param_node,
|
||||||
buf_sprintf("inline parameter not allowed in extern function"));
|
buf_sprintf("comptime parameter not allowed in extern function"));
|
||||||
return g->builtin_types.entry_invalid;
|
return g->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
return get_generic_fn_type(g, &fn_type_id);
|
return get_generic_fn_type(g, &fn_type_id);
|
||||||
|
@ -250,7 +250,7 @@ static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ParamDecl = option("noalias" | "inline") option("Symbol" ":") TypeExpr | "..."
|
ParamDecl = option("noalias" | "comptime") option(Symbol ":") TypeExpr | "..."
|
||||||
*/
|
*/
|
||||||
static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
|
static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
|
||||||
Token *token = &pc->tokens->at(*token_index);
|
Token *token = &pc->tokens->at(*token_index);
|
||||||
@ -266,7 +266,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
|
|||||||
node->data.param_decl.is_noalias = true;
|
node->data.param_decl.is_noalias = true;
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
token = &pc->tokens->at(*token_index);
|
token = &pc->tokens->at(*token_index);
|
||||||
} else if (token->id == TokenIdKeywordInline) {
|
} else if (token->id == TokenIdKeywordCompTime) {
|
||||||
node->data.param_decl.is_inline = true;
|
node->data.param_decl.is_inline = true;
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
token = &pc->tokens->at(*token_index);
|
token = &pc->tokens->at(*token_index);
|
||||||
@ -1492,7 +1492,7 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
VariableDeclaration = option("inline") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
|
VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
|
||||||
*/
|
*/
|
||||||
static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,
|
static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,
|
||||||
VisibMod visib_mod)
|
VisibMod visib_mod)
|
||||||
@ -1501,9 +1501,9 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
|
|||||||
Token *var_token;
|
Token *var_token;
|
||||||
|
|
||||||
bool is_const;
|
bool is_const;
|
||||||
bool is_inline;
|
bool is_comptime;
|
||||||
if (first_token->id == TokenIdKeywordInline) {
|
if (first_token->id == TokenIdKeywordCompTime) {
|
||||||
is_inline = true;
|
is_comptime = true;
|
||||||
var_token = &pc->tokens->at(*token_index + 1);
|
var_token = &pc->tokens->at(*token_index + 1);
|
||||||
|
|
||||||
if (var_token->id == TokenIdKeywordVar) {
|
if (var_token->id == TokenIdKeywordVar) {
|
||||||
@ -1518,12 +1518,12 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
|
|||||||
|
|
||||||
*token_index += 2;
|
*token_index += 2;
|
||||||
} else if (first_token->id == TokenIdKeywordVar) {
|
} else if (first_token->id == TokenIdKeywordVar) {
|
||||||
is_inline = false;
|
is_comptime = false;
|
||||||
is_const = false;
|
is_const = false;
|
||||||
var_token = first_token;
|
var_token = first_token;
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
} else if (first_token->id == TokenIdKeywordConst) {
|
} else if (first_token->id == TokenIdKeywordConst) {
|
||||||
is_inline = false;
|
is_comptime = false;
|
||||||
is_const = true;
|
is_const = true;
|
||||||
var_token = first_token;
|
var_token = first_token;
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
@ -1535,7 +1535,7 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
|
|||||||
|
|
||||||
AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_token);
|
AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_token);
|
||||||
|
|
||||||
node->data.variable_declaration.is_inline = is_inline;
|
node->data.variable_declaration.is_inline = is_comptime;
|
||||||
node->data.variable_declaration.is_const = is_const;
|
node->data.variable_declaration.is_const = is_const;
|
||||||
node->data.variable_declaration.visib_mod = visib_mod;
|
node->data.variable_declaration.visib_mod = visib_mod;
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ static const struct ZigKeyword zig_keywords[] = {
|
|||||||
{"asm", TokenIdKeywordAsm},
|
{"asm", TokenIdKeywordAsm},
|
||||||
{"break", TokenIdKeywordBreak},
|
{"break", TokenIdKeywordBreak},
|
||||||
{"coldcc", TokenIdKeywordColdCC},
|
{"coldcc", TokenIdKeywordColdCC},
|
||||||
|
{"comptime", TokenIdKeywordCompTime},
|
||||||
{"const", TokenIdKeywordConst},
|
{"const", TokenIdKeywordConst},
|
||||||
{"continue", TokenIdKeywordContinue},
|
{"continue", TokenIdKeywordContinue},
|
||||||
{"defer", TokenIdKeywordDefer},
|
{"defer", TokenIdKeywordDefer},
|
||||||
@ -1475,6 +1476,7 @@ const char * token_name(TokenId id) {
|
|||||||
case TokenIdKeywordError: return "error";
|
case TokenIdKeywordError: return "error";
|
||||||
case TokenIdKeywordType: return "type";
|
case TokenIdKeywordType: return "type";
|
||||||
case TokenIdKeywordInline: return "inline";
|
case TokenIdKeywordInline: return "inline";
|
||||||
|
case TokenIdKeywordCompTime: return "comptime";
|
||||||
case TokenIdKeywordDefer: return "defer";
|
case TokenIdKeywordDefer: return "defer";
|
||||||
case TokenIdKeywordColdCC: return "coldcc";
|
case TokenIdKeywordColdCC: return "coldcc";
|
||||||
case TokenIdKeywordNakedCC: return "nakedcc";
|
case TokenIdKeywordNakedCC: return "nakedcc";
|
||||||
|
@ -43,6 +43,7 @@ enum TokenId {
|
|||||||
TokenIdKeywordError,
|
TokenIdKeywordError,
|
||||||
TokenIdKeywordType,
|
TokenIdKeywordType,
|
||||||
TokenIdKeywordInline,
|
TokenIdKeywordInline,
|
||||||
|
TokenIdKeywordCompTime,
|
||||||
TokenIdKeywordDefer,
|
TokenIdKeywordDefer,
|
||||||
TokenIdKeywordThis,
|
TokenIdKeywordThis,
|
||||||
TokenIdKeywordColdCC,
|
TokenIdKeywordColdCC,
|
||||||
|
@ -16,7 +16,7 @@ var argv: &&u8 = undefined;
|
|||||||
export nakedcc fn _start() -> unreachable {
|
export nakedcc fn _start() -> unreachable {
|
||||||
@setFnVisible(this, want_start_symbol);
|
@setFnVisible(this, want_start_symbol);
|
||||||
|
|
||||||
inline switch (@compileVar("arch")) {
|
switch (@compileVar("arch")) {
|
||||||
Arch.x86_64 => {
|
Arch.x86_64 => {
|
||||||
argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize));
|
argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize));
|
||||||
argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
|
argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8));
|
||||||
|
@ -241,7 +241,7 @@ fn parseFormValueRefLen(in_stream: &io.InStream, size: usize) -> %FormValue {
|
|||||||
return FormValue.Ref { buf };
|
return FormValue.Ref { buf };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseFormValueRef(in_stream: &io.InStream, inline T: type) -> %FormValue {
|
fn parseFormValueRef(in_stream: &io.InStream, comptime T: type) -> %FormValue {
|
||||||
const block_len = %return in_stream.readIntLe(T);
|
const block_len = %return in_stream.readIntLe(T);
|
||||||
return parseFormValueRefLen(in_stream, block_len);
|
return parseFormValueRefLen(in_stream, block_len);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
pub inline fn swapIfLe(inline T: type, x: T) -> T {
|
pub inline fn swapIfLe(comptime T: type, x: T) -> T {
|
||||||
swapIf(false, T, x)
|
swapIf(false, T, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn swapIfBe(inline T: type, x: T) -> T {
|
pub inline fn swapIfBe(comptime T: type, x: T) -> T {
|
||||||
swapIf(true, T, x)
|
swapIf(true, T, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn swapIf(is_be: bool, inline T: type, x: T) -> T {
|
pub inline fn swapIf(is_be: bool, comptime T: type, x: T) -> T {
|
||||||
if (@compileVar("is_big_endian") == is_be) swap(T, x) else x
|
if (@compileVar("is_big_endian") == is_be) swap(T, x) else x
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn swap(inline T: type, x: T) -> T {
|
pub fn swap(comptime T: type, x: T) -> T {
|
||||||
const x_slice = ([]u8)((&const x)[0...1]);
|
const x_slice = ([]u8)((&const x)[0...1]);
|
||||||
var result: T = undefined;
|
var result: T = undefined;
|
||||||
const result_slice = ([]u8)((&result)[0...1]);
|
const result_slice = ([]u8)((&result)[0...1]);
|
||||||
|
@ -7,8 +7,8 @@ const Allocator = mem.Allocator;
|
|||||||
const want_modification_safety = !@compileVar("is_release");
|
const want_modification_safety = !@compileVar("is_release");
|
||||||
const debug_u32 = if (want_modification_safety) u32 else void;
|
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,
|
pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)->u32,
|
||||||
inline eql: fn(a: K, b: K)->bool) -> type
|
comptime eql: fn(a: K, b: K)->bool) -> type
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
entries: []Entry,
|
entries: []Entry,
|
||||||
|
18
std/io.zig
18
std/io.zig
@ -105,7 +105,7 @@ pub const OutStream = struct {
|
|||||||
return byte_count;
|
return byte_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn printInt(self: &OutStream, inline T: type, x: T) -> %usize {
|
pub fn printInt(self: &OutStream, comptime T: type, x: T) -> %usize {
|
||||||
// TODO replace max_u64_base10_digits with math.log10(math.pow(2, @sizeOf(T)))
|
// TODO replace max_u64_base10_digits with math.log10(math.pow(2, @sizeOf(T)))
|
||||||
if (self.index + max_u64_base10_digits >= self.buffer.len) {
|
if (self.index + max_u64_base10_digits >= self.buffer.len) {
|
||||||
%return self.flush();
|
%return self.flush();
|
||||||
@ -255,22 +255,22 @@ pub const InStream = struct {
|
|||||||
return result[0];
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readIntLe(is: &InStream, inline T: type) -> %T {
|
pub fn readIntLe(is: &InStream, comptime T: type) -> %T {
|
||||||
is.readInt(false, T)
|
is.readInt(false, T)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readIntBe(is: &InStream, inline T: type) -> %T {
|
pub fn readIntBe(is: &InStream, comptime T: type) -> %T {
|
||||||
is.readInt(true, T)
|
is.readInt(true, T)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readInt(is: &InStream, is_be: bool, inline T: type) -> %T {
|
pub fn readInt(is: &InStream, is_be: bool, comptime T: type) -> %T {
|
||||||
var result: T = undefined;
|
var result: T = undefined;
|
||||||
const result_slice = ([]u8)((&result)[0...1]);
|
const result_slice = ([]u8)((&result)[0...1]);
|
||||||
%return is.readNoEof(result_slice);
|
%return is.readNoEof(result_slice);
|
||||||
return endian.swapIf(!is_be, T, result);
|
return endian.swapIf(!is_be, T, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readVarInt(is: &InStream, is_be: bool, inline T: type, size: usize) -> %T {
|
pub fn readVarInt(is: &InStream, is_be: bool, comptime T: type, size: usize) -> %T {
|
||||||
assert(size <= @sizeOf(T));
|
assert(size <= @sizeOf(T));
|
||||||
assert(size <= 8);
|
assert(size <= 8);
|
||||||
var input_buf: [8]u8 = undefined;
|
var input_buf: [8]u8 = undefined;
|
||||||
@ -355,7 +355,7 @@ pub const InStream = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parseUnsigned(inline T: type, buf: []u8, radix: u8) -> %T {
|
pub fn parseUnsigned(comptime T: type, buf: []u8, radix: u8) -> %T {
|
||||||
var x: T = 0;
|
var x: T = 0;
|
||||||
|
|
||||||
for (buf) |c| {
|
for (buf) |c| {
|
||||||
@ -381,11 +381,11 @@ fn charToDigit(c: u8, radix: u8) -> %u8 {
|
|||||||
return if (value >= radix) error.InvalidChar else value;
|
return if (value >= radix) error.InvalidChar else value;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bufPrintInt(inline T: type, out_buf: []u8, x: T) -> usize {
|
pub fn bufPrintInt(comptime T: type, out_buf: []u8, x: T) -> usize {
|
||||||
if (T.is_signed) bufPrintSigned(T, out_buf, x) else bufPrintUnsigned(T, out_buf, x)
|
if (T.is_signed) bufPrintSigned(T, out_buf, x) else bufPrintUnsigned(T, out_buf, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bufPrintSigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
fn bufPrintSigned(comptime T: type, out_buf: []u8, x: T) -> usize {
|
||||||
const uint = @intType(false, T.bit_count);
|
const uint = @intType(false, T.bit_count);
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
out_buf[0] = '-';
|
out_buf[0] = '-';
|
||||||
@ -395,7 +395,7 @@ fn bufPrintSigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize {
|
fn bufPrintUnsigned(comptime T: type, out_buf: []u8, x: T) -> usize {
|
||||||
var buf: [max_u64_base10_digits]u8 = undefined;
|
var buf: [max_u64_base10_digits]u8 = undefined;
|
||||||
var a = x;
|
var a = x;
|
||||||
var index: usize = buf.len;
|
var index: usize = buf.len;
|
||||||
|
@ -3,7 +3,7 @@ const assert = debug.assert;
|
|||||||
const mem = @import("mem.zig");
|
const mem = @import("mem.zig");
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
pub fn List(inline T: type) -> type{
|
pub fn List(comptime T: type) -> type{
|
||||||
struct {
|
struct {
|
||||||
const Self = this;
|
const Self = this;
|
||||||
|
|
||||||
|
@ -13,19 +13,19 @@ pub fn max(x: var, y: var) -> @typeOf(x + y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
error Overflow;
|
error Overflow;
|
||||||
pub fn mulOverflow(inline T: type, a: T, b: T) -> %T {
|
pub fn mulOverflow(comptime T: type, a: T, b: T) -> %T {
|
||||||
var answer: T = undefined;
|
var answer: T = undefined;
|
||||||
if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||||
}
|
}
|
||||||
pub fn addOverflow(inline T: type, a: T, b: T) -> %T {
|
pub fn addOverflow(comptime T: type, a: T, b: T) -> %T {
|
||||||
var answer: T = undefined;
|
var answer: T = undefined;
|
||||||
if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||||
}
|
}
|
||||||
pub fn subOverflow(inline T: type, a: T, b: T) -> %T {
|
pub fn subOverflow(comptime T: type, a: T, b: T) -> %T {
|
||||||
var answer: T = undefined;
|
var answer: T = undefined;
|
||||||
if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||||
}
|
}
|
||||||
pub fn shlOverflow(inline T: type, a: T, b: T) -> %T {
|
pub fn shlOverflow(comptime T: type, a: T, b: T) -> %T {
|
||||||
var answer: T = undefined;
|
var answer: T = undefined;
|
||||||
if (@shlWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
if (@shlWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
||||||
}
|
}
|
||||||
|
16
std/mem.zig
16
std/mem.zig
@ -15,7 +15,7 @@ pub const Allocator = struct {
|
|||||||
context: ?&Context,
|
context: ?&Context,
|
||||||
|
|
||||||
/// Aborts the program if an allocation fails.
|
/// Aborts the program if an allocation fails.
|
||||||
fn checkedAlloc(self: &Allocator, inline T: type, n: usize) -> []T {
|
fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T {
|
||||||
alloc(self, T, n) %% |err| {
|
alloc(self, T, n) %% |err| {
|
||||||
// TODO var args printf
|
// TODO var args printf
|
||||||
%%io.stderr.write("allocation failure: ");
|
%%io.stderr.write("allocation failure: ");
|
||||||
@ -25,37 +25,37 @@ pub const Allocator = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc(self: &Allocator, inline T: type, n: usize) -> %[]T {
|
fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T {
|
||||||
const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
|
const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
|
||||||
([]T)(%return self.allocFn(self, byte_count))
|
([]T)(%return self.allocFn(self, byte_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn realloc(self: &Allocator, inline T: type, old_mem: []T, n: usize) -> %[]T {
|
fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) -> %[]T {
|
||||||
const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
|
const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
|
||||||
([]T)(%return self.reallocFn(self, ([]u8)(old_mem), byte_count))
|
([]T)(%return self.reallocFn(self, ([]u8)(old_mem), byte_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO mem: []var and get rid of 2nd param
|
// TODO mem: []var and get rid of 2nd param
|
||||||
fn free(self: &Allocator, inline T: type, mem: []T) {
|
fn free(self: &Allocator, comptime T: type, mem: []T) {
|
||||||
self.freeFn(self, ([]u8)(mem));
|
self.freeFn(self, ([]u8)(mem));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Copy all of source into dest at position 0.
|
/// Copy all of source into dest at position 0.
|
||||||
/// dest.len must be >= source.len.
|
/// dest.len must be >= source.len.
|
||||||
pub fn copy(inline T: type, dest: []T, source: []const T) {
|
pub fn copy(comptime T: type, dest: []T, source: []const T) {
|
||||||
@setDebugSafety(this, false);
|
@setDebugSafety(this, false);
|
||||||
assert(dest.len >= source.len);
|
assert(dest.len >= source.len);
|
||||||
for (source) |s, i| dest[i] = s;
|
for (source) |s, i| dest[i] = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(inline T: type, dest: []T, value: T) {
|
pub fn set(comptime T: type, dest: []T, value: T) {
|
||||||
for (dest) |*d| *d = value;
|
for (dest) |*d| *d = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return < 0, == 0, or > 0 if memory a is less than, equal to, or greater than,
|
/// Return < 0, == 0, or > 0 if memory a is less than, equal to, or greater than,
|
||||||
/// memory b, respectively.
|
/// memory b, respectively.
|
||||||
pub fn cmp(inline T: type, a: []const T, b: []const T) -> Cmp {
|
pub fn cmp(comptime T: type, a: []const T, b: []const T) -> Cmp {
|
||||||
const n = math.min(a.len, b.len);
|
const n = math.min(a.len, b.len);
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < n; i += 1) {
|
while (i < n; i += 1) {
|
||||||
@ -66,7 +66,7 @@ pub fn cmp(inline T: type, a: []const T, b: []const T) -> Cmp {
|
|||||||
return if (a.len > b.len) Cmp.Greater else if (a.len < b.len) Cmp.Less else Cmp.Equal;
|
return if (a.len > b.len) Cmp.Greater else if (a.len < b.len) Cmp.Less else Cmp.Equal;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sliceAsInt(buf: []u8, is_be: bool, inline T: type) -> T {
|
pub fn sliceAsInt(buf: []u8, is_be: bool, comptime T: type) -> T {
|
||||||
var result: T = undefined;
|
var result: T = undefined;
|
||||||
const result_slice = ([]u8)((&result)[0...1]);
|
const result_slice = ([]u8)((&result)[0...1]);
|
||||||
set(u8, result_slice, 0);
|
set(u8, result_slice, 0);
|
||||||
|
18
std/rand.zig
18
std/rand.zig
@ -29,7 +29,7 @@ pub const Rand = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an integer with random bits.
|
/// Get an integer with random bits.
|
||||||
pub fn scalar(r: &Rand, inline T: type) -> T {
|
pub fn scalar(r: &Rand, comptime T: type) -> T {
|
||||||
if (T == usize) {
|
if (T == usize) {
|
||||||
return r.rng.get();
|
return r.rng.get();
|
||||||
} else {
|
} else {
|
||||||
@ -59,7 +59,7 @@ pub const Rand = struct {
|
|||||||
/// Get a random unsigned integer with even distribution between `start`
|
/// Get a random unsigned integer with even distribution between `start`
|
||||||
/// inclusive and `end` exclusive.
|
/// inclusive and `end` exclusive.
|
||||||
// TODO support signed integers and then rename to "range"
|
// TODO support signed integers and then rename to "range"
|
||||||
pub fn rangeUnsigned(r: &Rand, inline T: type, start: T, end: T) -> T {
|
pub fn rangeUnsigned(r: &Rand, comptime T: type, start: T, end: T) -> T {
|
||||||
const range = end - start;
|
const range = end - start;
|
||||||
const leftover = @maxValue(T) % range;
|
const leftover = @maxValue(T) % range;
|
||||||
const upper_bound = @maxValue(T) - leftover;
|
const upper_bound = @maxValue(T) - leftover;
|
||||||
@ -75,7 +75,7 @@ pub const Rand = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a floating point value in the range 0.0..1.0.
|
/// Get a floating point value in the range 0.0..1.0.
|
||||||
pub fn float(r: &Rand, inline T: type) -> T {
|
pub fn float(r: &Rand, comptime T: type) -> T {
|
||||||
// TODO Implement this way instead:
|
// 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 mask = ((1 << @float_mantissa_bit_count(T)) - 1);
|
||||||
@ -94,12 +94,12 @@ pub const Rand = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn MersenneTwister(
|
fn MersenneTwister(
|
||||||
inline int: type, inline n: usize, inline m: usize, inline r: int,
|
comptime int: type, comptime n: usize, comptime m: usize, comptime r: int,
|
||||||
inline a: int,
|
comptime a: int,
|
||||||
inline u: int, inline d: int,
|
comptime u: int, comptime d: int,
|
||||||
inline s: int, inline b: int,
|
comptime s: int, comptime b: int,
|
||||||
inline t: int, inline c: int,
|
comptime t: int, comptime c: int,
|
||||||
inline l: int, inline f: int) -> type
|
comptime l: int, comptime f: int) -> type
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
const Self = this;
|
const Self = this;
|
||||||
|
@ -5,13 +5,13 @@ const math = @import("math.zig");
|
|||||||
|
|
||||||
pub const Cmp = math.Cmp;
|
pub const Cmp = math.Cmp;
|
||||||
|
|
||||||
pub fn sort(inline T: type, array: []T, inline cmp: fn(a: &const T, b: &const T)->Cmp) {
|
pub fn sort(comptime T: type, array: []T, comptime cmp: fn(a: &const T, b: &const T)->Cmp) {
|
||||||
if (array.len > 0) {
|
if (array.len > 0) {
|
||||||
quicksort(T, array, 0, array.len - 1, cmp);
|
quicksort(T, array, 0, array.len - 1, cmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quicksort(inline T: type, array: []T, left: usize, right: usize, inline cmp: fn(a: &const T, b: &const T)->Cmp) {
|
fn quicksort(comptime T: type, array: []T, left: usize, right: usize, comptime cmp: fn(a: &const T, b: &const T)->Cmp) {
|
||||||
var i = left;
|
var i = left;
|
||||||
var j = right;
|
var j = right;
|
||||||
const p = (i + j) / 2;
|
const p = (i + j) / 2;
|
||||||
|
@ -4,7 +4,7 @@ pub fn eql(a: []const u8, b: []const u8) -> bool {
|
|||||||
sliceEql(u8, a, b)
|
sliceEql(u8, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool {
|
pub fn sliceEql(comptime T: type, a: []const T, b: []const T) -> bool {
|
||||||
if (a.len != b.len) return false;
|
if (a.len != b.len) return false;
|
||||||
for (a) |item, index| {
|
for (a) |item, index| {
|
||||||
if (b[index] != item) return false;
|
if (b[index] != item) return false;
|
||||||
|
@ -25,17 +25,17 @@ fn testStaticAddOne() {
|
|||||||
fn inlinedLoop() {
|
fn inlinedLoop() {
|
||||||
@setFnTest(this);
|
@setFnTest(this);
|
||||||
|
|
||||||
inline var i = 0;
|
comptime var i = 0;
|
||||||
inline var sum = 0;
|
comptime var sum = 0;
|
||||||
inline while (i <= 5; i += 1)
|
inline while (i <= 5; i += 1)
|
||||||
sum += i;
|
sum += i;
|
||||||
assert(sum == 15);
|
assert(sum == 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gimme1or2(inline a: bool) -> i32 {
|
fn gimme1or2(comptime a: bool) -> i32 {
|
||||||
const x: i32 = 1;
|
const x: i32 = 1;
|
||||||
const y: i32 = 2;
|
const y: i32 = 2;
|
||||||
inline var z: i32 = if (a) x else y;
|
comptime var z: i32 = if (a) x else y;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
fn inlineVariableGetsResultOfConstIf() {
|
fn inlineVariableGetsResultOfConstIf() {
|
||||||
|
@ -8,11 +8,11 @@ fn simpleGenericFn() {
|
|||||||
assert(add(2, 3) == 5);
|
assert(add(2, 3) == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max(inline T: type, a: T, b: T) -> T {
|
fn max(comptime T: type, a: T, b: T) -> T {
|
||||||
return if (a > b) a else b;
|
return if (a > b) a else b;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(inline a: i32, b: i32) -> i32 {
|
fn add(comptime a: i32, b: i32) -> i32 {
|
||||||
return @staticEval(a) + b;
|
return @staticEval(a) + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,11 +67,11 @@ fn max_f64(a: f64, b: f64) -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn List(inline T: type) -> type {
|
pub fn List(comptime T: type) -> type {
|
||||||
SmallList(T, 8)
|
SmallList(T, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SmallList(inline T: type, inline STATIC_SIZE: usize) -> type {
|
pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
|
||||||
struct {
|
struct {
|
||||||
items: []T,
|
items: []T,
|
||||||
length: usize,
|
length: usize,
|
||||||
@ -100,7 +100,7 @@ fn genericStruct() {
|
|||||||
assert(a1.value == a1.getVal());
|
assert(a1.value == a1.getVal());
|
||||||
assert(b1.getVal());
|
assert(b1.getVal());
|
||||||
}
|
}
|
||||||
fn GenNode(inline T: type) -> type {
|
fn GenNode(comptime T: type) -> type {
|
||||||
struct {
|
struct {
|
||||||
value: T,
|
value: T,
|
||||||
next: ?&GenNode(T),
|
next: ?&GenNode(T),
|
||||||
@ -113,7 +113,7 @@ fn constDeclsInStruct() {
|
|||||||
|
|
||||||
assert(GenericDataThing(3).count_plus_one == 4);
|
assert(GenericDataThing(3).count_plus_one == 4);
|
||||||
}
|
}
|
||||||
fn GenericDataThing(inline count: isize) -> type {
|
fn GenericDataThing(comptime count: isize) -> type {
|
||||||
struct {
|
struct {
|
||||||
const count_plus_one = count + 1;
|
const count_plus_one = count + 1;
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ fn useGenericParamInGenericParam() {
|
|||||||
|
|
||||||
assert(aGenericFn(i32, 3, 4) == 7);
|
assert(aGenericFn(i32, 3, 4) == 7);
|
||||||
}
|
}
|
||||||
fn aGenericFn(inline T: type, inline a: T, b: T) -> T {
|
fn aGenericFn(comptime T: type, comptime a: T, b: T) -> T {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +137,6 @@ fn genericFnWithImplicitCast() {
|
|||||||
assert(getFirstByte(u16, []u16 {0, 13}) == 0);
|
assert(getFirstByte(u16, []u16 {0, 13}) == 0);
|
||||||
}
|
}
|
||||||
fn getByte(ptr: ?&u8) -> u8 {*??ptr}
|
fn getByte(ptr: ?&u8) -> u8 {*??ptr}
|
||||||
fn getFirstByte(inline T: type, mem: []T) -> u8 {
|
fn getFirstByte(comptime T: type, mem: []T) -> u8 {
|
||||||
getByte((&u8)(&mem[0]))
|
getByte((&u8)(&mem[0]))
|
||||||
}
|
}
|
||||||
|
@ -292,10 +292,10 @@ fn genericMallocFree() {
|
|||||||
memFree(u8, a);
|
memFree(u8, a);
|
||||||
}
|
}
|
||||||
const some_mem : [100]u8 = undefined;
|
const some_mem : [100]u8 = undefined;
|
||||||
fn memAlloc(inline T: type, n: usize) -> %[]T {
|
fn memAlloc(comptime T: type, n: usize) -> %[]T {
|
||||||
return (&T)(&some_mem[0])[0...n];
|
return (&T)(&some_mem[0])[0...n];
|
||||||
}
|
}
|
||||||
fn memFree(inline T: type, mem: []T) { }
|
fn memFree(comptime T: type, mem: []T) { }
|
||||||
|
|
||||||
|
|
||||||
fn castUndefined() {
|
fn castUndefined() {
|
||||||
|
@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
|
|||||||
|
|
||||||
const module = this;
|
const module = this;
|
||||||
|
|
||||||
fn Point(inline T: type) -> type {
|
fn Point(comptime T: type) -> type {
|
||||||
struct {
|
struct {
|
||||||
const Self = this;
|
const Self = this;
|
||||||
x: T,
|
x: T,
|
||||||
|
@ -1195,7 +1195,7 @@ const invalid = foo > foo;
|
|||||||
)SOURCE", 1, ".tmp_source.zig:3:21: error: operator not allowed for type 'fn()'");
|
)SOURCE", 1, ".tmp_source.zig:3:21: error: operator not allowed for type 'fn()'");
|
||||||
|
|
||||||
add_compile_fail_case("generic function instance with non-constant expression", R"SOURCE(
|
add_compile_fail_case("generic function instance with non-constant expression", R"SOURCE(
|
||||||
fn foo(inline x: i32, y: i32) -> i32 { return x + y; }
|
fn foo(comptime x: i32, y: i32) -> i32 { return x + y; }
|
||||||
fn test1(a: i32, b: i32) -> i32 {
|
fn test1(a: i32, b: i32) -> i32 {
|
||||||
return foo(a, b);
|
return foo(a, b);
|
||||||
}
|
}
|
||||||
@ -1407,18 +1407,18 @@ fn f() {
|
|||||||
}
|
}
|
||||||
)SOURCE", 1, ".tmp_source.zig:3:13: error: unable to evaluate constant expression");
|
)SOURCE", 1, ".tmp_source.zig:3:13: error: unable to evaluate constant expression");
|
||||||
|
|
||||||
add_compile_fail_case("export function with inline parameter", R"SOURCE(
|
add_compile_fail_case("export function with comptime parameter", R"SOURCE(
|
||||||
export fn foo(inline x: i32, y: i32) -> i32{
|
export fn foo(comptime x: i32, y: i32) -> i32{
|
||||||
x + y
|
x + y
|
||||||
}
|
}
|
||||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: inline parameter not allowed in extern function");
|
)SOURCE", 1, ".tmp_source.zig:2:15: error: comptime parameter not allowed in extern function");
|
||||||
|
|
||||||
add_compile_fail_case("extern function with inline parameter", R"SOURCE(
|
add_compile_fail_case("extern function with comptime parameter", R"SOURCE(
|
||||||
extern fn foo(inline x: i32, y: i32) -> i32;
|
extern fn foo(comptime x: i32, y: i32) -> i32;
|
||||||
fn f() -> i32 {
|
fn f() -> i32 {
|
||||||
foo(1, 2)
|
foo(1, 2)
|
||||||
}
|
}
|
||||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: inline parameter not allowed in extern function");
|
)SOURCE", 1, ".tmp_source.zig:2:15: error: comptime parameter not allowed in extern function");
|
||||||
|
|
||||||
add_compile_fail_case("convert fixed size array to slice with invalid size", R"SOURCE(
|
add_compile_fail_case("convert fixed size array to slice with invalid size", R"SOURCE(
|
||||||
fn f() {
|
fn f() {
|
||||||
@ -1429,12 +1429,12 @@ fn f() {
|
|||||||
|
|
||||||
add_compile_fail_case("non-pure function returns type", R"SOURCE(
|
add_compile_fail_case("non-pure function returns type", R"SOURCE(
|
||||||
var a: u32 = 0;
|
var a: u32 = 0;
|
||||||
pub fn List(inline T: type) -> type {
|
pub fn List(comptime T: type) -> type {
|
||||||
a += 1;
|
a += 1;
|
||||||
SmallList(T, 8)
|
SmallList(T, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SmallList(inline T: type, inline STATIC_SIZE: usize) -> type {
|
pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
|
||||||
struct {
|
struct {
|
||||||
items: []T,
|
items: []T,
|
||||||
length: usize,
|
length: usize,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user