explicitly return from blocks

instead of last statement being expression value

closes #629
This commit is contained in:
Andrew Kelley 2017-12-22 00:50:30 -05:00
parent 8bc523219c
commit d917815d81
114 changed files with 1203 additions and 1231 deletions

View File

@ -49,7 +49,7 @@ fn gen(in: &io.InStream, out: &io.OutStream) {
if (err == error.EndOfStream) {
return;
}
std.debug.panic("{}", err)
std.debug.panic("{}", err);
};
switch (state) {
State.Start => switch (byte) {

View File

@ -3021,14 +3021,13 @@ const assert = @import("std").debug.assert;</code></pre>
<pre><code class="zig">const assert = @import("std").debug.assert;
// Functions are declared like this
// The last expression in the function can be used as the return value.
fn add(a: i8, b: i8) -&gt; i8 {
if (a == 0) {
// You can still return manually if needed.
return b;
}
a + b
return a + b;
}
// The export specifier makes a function externally visible in the generated
@ -5847,7 +5846,7 @@ ParamDeclList = "(" list(ParamDecl, ",") ")"
ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")
Block = option(Symbol ":") "{" many(Statement) option(Expression) "}"
Block = option(Symbol ":") "{" many(Statement) "}"
Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"

View File

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

View File

@ -111,11 +111,11 @@ pub const Parser = struct {
}
pub fn parse(self: &Parser) -> %&ast.NodeRoot {
const result = self.parseInner() %% |err| {
const result = self.parseInner() %% |err| x: {
if (self.cleanup_root_node) |root_node| {
self.freeAst(root_node);
}
err
break :x err;
};
self.cleanup_root_node = null;
return result;
@ -125,12 +125,12 @@ pub const Parser = struct {
var stack = self.initUtilityArrayList(State);
defer self.deinitUtilityArrayList(stack);
const root_node = {
const root_node = x: {
const root_node = %return self.createRoot();
%defer self.allocator.destroy(root_node);
// This stack append has to succeed for freeAst to work
%return stack.append(State.TopLevel);
root_node
break :x root_node;
};
assert(self.cleanup_root_node == null);
self.cleanup_root_node = root_node;
@ -462,7 +462,7 @@ pub const Parser = struct {
} else if (token.id == Token.Id.Keyword_noalias) {
param_decl.noalias_token = token;
token = self.getNextToken();
};
}
if (token.id == Token.Id.Identifier) {
const next_token = self.getNextToken();
if (next_token.id == Token.Id.Colon) {
@ -793,14 +793,14 @@ pub const Parser = struct {
}
fn getNextToken(self: &Parser) -> Token {
return if (self.put_back_count != 0) {
if (self.put_back_count != 0) {
const put_back_index = self.put_back_count - 1;
const put_back_token = self.put_back_tokens[put_back_index];
self.put_back_count = put_back_index;
put_back_token
return put_back_token;
} else {
self.tokenizer.next()
};
return self.tokenizer.next();
}
}
const RenderAstFrame = struct {
@ -873,7 +873,7 @@ pub const Parser = struct {
Token.Id.Keyword_pub => %return stream.print("pub "),
Token.Id.Keyword_export => %return stream.print("export "),
else => unreachable,
};
}
}
if (fn_proto.extern_token) |extern_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
@ -1102,7 +1102,7 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
// TODO test for memory leaks
// TODO test for valid frees
fn testCanonical(source: []const u8) {
const needed_alloc_count = {
const needed_alloc_count = x: {
// Try it once with unlimited memory, make sure it works
var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
@ -1116,7 +1116,7 @@ fn testCanonical(source: []const u8) {
@panic("test failed");
}
failing_allocator.allocator.free(result_source);
failing_allocator.index
break :x failing_allocator.index;
};
// TODO make this pass

View File

@ -26,7 +26,6 @@ struct ScopeFnDef;
struct TypeTableEntry;
struct VariableTableEntry;
struct ErrorTableEntry;
struct LabelTableEntry;
struct BuiltinFnEntry;
struct TypeStructField;
struct CodeGen;
@ -54,7 +53,6 @@ struct IrExecutable {
size_t *backward_branch_count;
size_t backward_branch_quota;
bool invalid;
ZigList<LabelTableEntry *> all_labels;
ZigList<IrGotoItem> goto_list;
bool is_inline;
FnTableEntry *fn_entry;
@ -452,7 +450,6 @@ struct AstNodeParamDecl {
struct AstNodeBlock {
Buf *name;
ZigList<AstNode *> statements;
bool last_statement_is_result_expression;
};
enum ReturnKind {
@ -1644,12 +1641,6 @@ struct ErrorTableEntry {
ConstExprValue *cached_error_name_val;
};
struct LabelTableEntry {
AstNode *decl_node;
IrBasicBlock *bb;
bool used;
};
enum ScopeId {
ScopeIdDecls,
ScopeIdBlock,
@ -1693,7 +1684,12 @@ struct ScopeDecls {
struct ScopeBlock {
Scope base;
HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
Buf *name;
IrBasicBlock *end_block;
IrInstruction *is_comptime;
ZigList<IrInstruction *> *incoming_values;
ZigList<IrBasicBlock *> *incoming_blocks;
bool safety_off;
AstNode *safety_set_node;
bool fast_math_off;

View File

@ -110,7 +110,7 @@ ScopeBlock *create_block_scope(AstNode *node, Scope *parent) {
assert(node->type == NodeTypeBlock);
ScopeBlock *scope = allocate<ScopeBlock>(1);
init_scope(&scope->base, ScopeIdBlock, node, parent);
scope->label_table.init(1);
scope->name = node->data.block.name;
return scope;
}

View File

@ -478,10 +478,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
AstNode *statement = node->data.block.statements.at(i);
print_indent(ar);
render_node_grouped(ar, statement);
if (!(i == node->data.block.statements.length - 1 &&
node->data.block.last_statement_is_result_expression)) {
fprintf(ar->f, ";");
}
fprintf(ar->f, "\n");
}
ar->indent -= ar->indent_size;

View File

@ -3514,7 +3514,11 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s
static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) {
assert(block_node->type == NodeTypeBlock);
ZigList<IrInstruction *> incoming_values = {0};
ZigList<IrBasicBlock *> incoming_blocks = {0};
ScopeBlock *scope_block = create_block_scope(block_node, parent_scope);
Scope *outer_block_scope = &scope_block->base;
Scope *child_scope = outer_block_scope;
@ -3528,9 +3532,15 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
return ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
}
if (block_node->data.block.name != nullptr) {
scope_block->incoming_blocks = &incoming_blocks;
scope_block->incoming_values = &incoming_values;
scope_block->end_block = ir_build_basic_block(irb, parent_scope, "BlockEnd");
scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, ir_should_inline(irb->exec, parent_scope));
}
bool is_continuation_unreachable = false;
IrInstruction *noreturn_return_value = nullptr;
IrInstruction *return_value = nullptr;
for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
AstNode *statement_node = block_node->data.block.statements.at(i);
@ -3548,39 +3558,31 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
// variable declarations start a new scope
IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)statement_value;
child_scope = decl_var_instruction->var->child_scope;
} else {
// label, defer, variable declaration will never be the result expression
if (block_node->data.block.last_statement_is_result_expression &&
i == block_node->data.block.statements.length - 1) {
// this is the result value statement
return_value = statement_value;
} else {
// there are more statements ahead of this one. this statement's value must be void
if (statement_value != irb->codegen->invalid_instruction) {
} else if (statement_value != irb->codegen->invalid_instruction) {
// this statement's value must be void
ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value));
}
}
}
}
if (is_continuation_unreachable) {
assert(noreturn_return_value != nullptr);
if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) {
return noreturn_return_value;
}
// control flow falls out of block
if (block_node->data.block.last_statement_is_result_expression) {
// return value was determined by the last statement
assert(return_value != nullptr);
} else {
// return value is implicitly void
assert(return_value == nullptr);
return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
incoming_blocks.append(irb->current_basic_block);
incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)));
}
if (block_node->data.block.name != nullptr) {
ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
return return_value;
ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
ir_set_cursor_at_end(irb, scope_block->end_block);
return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
} else {
ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)));
}
}
static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
@ -5952,6 +5954,31 @@ static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNo
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);
}
static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
IrInstruction *is_comptime;
if (ir_should_inline(irb->exec, break_scope)) {
is_comptime = ir_build_const_bool(irb, break_scope, node, true);
} else {
is_comptime = block_scope->is_comptime;
}
IrInstruction *result_value;
if (node->data.break_expr.expr) {
result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope);
if (result_value == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
} else {
result_value = ir_build_const_void(irb, break_scope, node);
}
IrBasicBlock *dest_block = block_scope->end_block;
ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false);
block_scope->incoming_blocks->append(irb->current_basic_block);
block_scope->incoming_values->append(result_value);
return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
}
static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) {
assert(node->type == NodeTypeBreak);
@ -5959,14 +5986,14 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *
// * function definition scope or global scope => error, break outside loop
// * defer expression scope => error, cannot break out of defer expression
// * loop scope => OK
// * (if it's a labeled break) labeled block => OK
Scope *search_scope = break_scope;
ScopeLoop *loop_scope;
bool saw_any_loop_scope = false;
for (;;) {
if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
if (saw_any_loop_scope) {
add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.break_expr.name)));
if (node->data.break_expr.name != nullptr) {
add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name)));
return irb->codegen->invalid_instruction;
} else {
add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop"));
@ -5977,13 +6004,20 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *
return irb->codegen->invalid_instruction;
} else if (search_scope->id == ScopeIdLoop) {
ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
saw_any_loop_scope = true;
if (node->data.break_expr.name == nullptr ||
(this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
{
loop_scope = this_loop_scope;
break;
}
} else if (search_scope->id == ScopeIdBlock) {
ScopeBlock *this_block_scope = (ScopeBlock *)search_scope;
if (node->data.break_expr.name != nullptr &&
(this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
{
assert(this_block_scope->end_block != nullptr);
return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);
}
}
search_scope = search_scope->parent;
}
@ -6022,10 +6056,9 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast
Scope *search_scope = continue_scope;
ScopeLoop *loop_scope;
bool saw_any_loop_scope = false;
for (;;) {
if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
if (saw_any_loop_scope) {
if (node->data.continue_expr.name != nullptr) {
add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name)));
return irb->codegen->invalid_instruction;
} else {
@ -6037,7 +6070,6 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast
return irb->codegen->invalid_instruction;
} else if (search_scope->id == ScopeIdLoop) {
ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
saw_any_loop_scope = true;
if (node->data.continue_expr.name == nullptr ||
(this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
{

View File

@ -748,7 +748,14 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
node->data.fn_call_expr.is_builtin = true;
return node;
} else if (token->id == TokenIdSymbol) {
}
AstNode *block_expr_node = ast_parse_block_expr(pc, token_index, false);
if (block_expr_node) {
return block_expr_node;
}
if (token->id == TokenIdSymbol) {
*token_index += 1;
AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
node->data.symbol_expr.symbol = token_buf(token);
@ -760,11 +767,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
return grouped_expr_node;
}
AstNode *block_expr_node = ast_parse_block_expr(pc, token_index, false);
if (block_expr_node) {
return block_expr_node;
}
AstNode *array_type_node = ast_parse_array_type_expr(pc, token_index, false);
if (array_type_node) {
return array_type_node;
@ -2145,9 +2147,6 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool
return nullptr;
}
/*
Label: token(Symbol) token(Colon)
*/
static bool statement_terminates_without_semicolon(AstNode *node) {
switch (node->type) {
case NodeTypeIfBoolExpr:
@ -2179,7 +2178,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
}
/*
Block = option(Symbol ":") "{" many(Statement) option(Expression) "}"
Block = option(Symbol ":") "{" many(Statement) "}"
Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | ExportDecl
*/
static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) {
@ -2220,6 +2219,12 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
}
for (;;) {
last_token = &pc->tokens->at(*token_index);
if (last_token->id == TokenIdRBrace) {
*token_index += 1;
return node;
}
AstNode *statement_node = ast_parse_local_var_decl(pc, token_index);
if (!statement_node)
statement_node = ast_parse_defer_expr(pc, token_index);
@ -2228,33 +2233,15 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
if (!statement_node)
statement_node = ast_parse_expression(pc, token_index, false);
bool semicolon_expected = true;
if (statement_node) {
node->data.block.statements.append(statement_node);
if (statement_terminates_without_semicolon(statement_node)) {
semicolon_expected = false;
} else {
if (statement_node->type == NodeTypeDefer) {
// defer without a block body requires a semicolon
Token *token = &pc->tokens->at(*token_index);
ast_expect_token(pc, token, TokenIdSemicolon);
}
}
}
node->data.block.last_statement_is_result_expression = statement_node && statement_node->type != NodeTypeDefer;
last_token = &pc->tokens->at(*token_index);
if (last_token->id == TokenIdRBrace) {
*token_index += 1;
return node;
} else if (!semicolon_expected) {
continue;
} else if (last_token->id == TokenIdSemicolon) {
*token_index += 1;
} else {
if (!statement_node) {
ast_invalid_token_error(pc, last_token);
}
node->data.block.statements.append(statement_node);
if (!statement_terminates_without_semicolon(statement_node)) {
ast_eat_token(pc, token_index, TokenIdSemicolon);
}
}
zig_unreachable();
}

View File

@ -171,6 +171,20 @@ static AstNode * trans_create_node(Context *c, NodeType id) {
return node;
}
static AstNode *trans_create_node_break(Context *c, Buf *label_name, AstNode *value_node) {
AstNode *node = trans_create_node(c, NodeTypeBreak);
node->data.break_expr.name = label_name;
node->data.break_expr.expr = value_node;
return node;
}
static AstNode *trans_create_node_return(Context *c, AstNode *value_node) {
AstNode *node = trans_create_node(c, NodeTypeReturnExpr);
node->data.return_expr.kind = ReturnKindUnconditional;
node->data.return_expr.expr = value_node;
return node;
}
static AstNode *trans_create_node_if(Context *c, AstNode *cond_node, AstNode *then_node, AstNode *else_node) {
AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
node->data.if_bool_expr.condition = cond_node;
@ -372,8 +386,7 @@ static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, AstNode *r
AstNode *block = trans_create_node(c, NodeTypeBlock);
block->data.block.statements.resize(1);
block->data.block.statements.items[0] = fn_call_node;
block->data.block.last_statement_is_result_expression = true;
block->data.block.statements.items[0] = trans_create_node_return(c, fn_call_node);
fn_def->data.fn_def.body = block;
return fn_def;
@ -1140,13 +1153,15 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco
} else {
// worst case
// c: lhs = rhs
// zig: {
// zig: x: {
// zig: const _tmp = rhs;
// zig: lhs = _tmp;
// zig: _tmp
// zig: break :x _tmp
// zig: }
TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
child_scope->node->data.block.name = label_name;
// const _tmp = rhs;
AstNode *rhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, rhs, TransRValue);
@ -1163,9 +1178,9 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco
trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,
trans_create_node_symbol(c, tmp_var_name)));
// _tmp
child_scope->node->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
child_scope->node->data.block.last_statement_is_result_expression = true;
// break :x _tmp
AstNode *tmp_symbol_node = trans_create_node_symbol(c, tmp_var_name);
child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, tmp_symbol_node));
return child_scope->node;
}
@ -1270,6 +1285,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
case BO_Comma:
{
TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
scope_block->node->data.block.name = label_name;
AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue);
if (lhs == nullptr)
return nullptr;
@ -1278,9 +1296,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue);
if (rhs == nullptr)
return nullptr;
scope_block->node->data.block.statements.append(maybe_suppress_result(c, result_used, rhs));
scope_block->node->data.block.last_statement_is_result_expression = true;
scope_block->node->data.block.statements.append(trans_create_node_break(c, label_name, maybe_suppress_result(c, result_used, rhs)));
return scope_block->node;
}
case BO_MulAssign:
@ -1320,14 +1336,16 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
} else {
// need more complexity. worst case, this looks like this:
// c: lhs >>= rhs
// zig: {
// zig: x: {
// zig: const _ref = &lhs;
// zig: *_ref = result_type(operation_type(*_ref) >> u5(rhs));
// zig: *_ref
// zig: break :x *_ref
// zig: }
// where u5 is the appropriate type
TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
child_scope->node->data.block.name = label_name;
// const _ref = &lhs;
AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
@ -1369,11 +1387,11 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
child_scope->node->data.block.statements.append(assign_statement);
if (result_used == ResultUsedYes) {
// *_ref
// break :x *_ref
child_scope->node->data.block.statements.append(
trans_create_node_break(c, label_name,
trans_create_node_prefix_op(c, PrefixOpDereference,
trans_create_node_symbol(c, tmp_var_name)));
child_scope->node->data.block.last_statement_is_result_expression = true;
trans_create_node_symbol(c, tmp_var_name))));
}
return child_scope->node;
@ -1394,13 +1412,15 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
} else {
// need more complexity. worst case, this looks like this:
// c: lhs += rhs
// zig: {
// zig: x: {
// zig: const _ref = &lhs;
// zig: *_ref = *_ref + rhs;
// zig: *_ref
// zig: break :x *_ref
// zig: }
TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
child_scope->node->data.block.name = label_name;
// const _ref = &lhs;
AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
@ -1427,11 +1447,11 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
rhs));
child_scope->node->data.block.statements.append(assign_statement);
// *_ref
// break :x *_ref
child_scope->node->data.block.statements.append(
trans_create_node_break(c, label_name,
trans_create_node_prefix_op(c, PrefixOpDereference,
trans_create_node_symbol(c, tmp_var_name)));
child_scope->node->data.block.last_statement_is_result_expression = true;
trans_create_node_symbol(c, tmp_var_name))));
return child_scope->node;
}
@ -1726,13 +1746,15 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
}
// worst case
// c: expr++
// zig: {
// zig: x: {
// zig: const _ref = &expr;
// zig: const _tmp = *_ref;
// zig: *_ref += 1;
// zig: _tmp
// zig: break :x _tmp
// zig: }
TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
child_scope->node->data.block.name = label_name;
// const _ref = &expr;
AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
@ -1758,9 +1780,8 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
trans_create_node_unsigned(c, 1));
child_scope->node->data.block.statements.append(assign_statement);
// _tmp
child_scope->node->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
child_scope->node->data.block.last_statement_is_result_expression = true;
// break :x _tmp
child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, trans_create_node_symbol(c, tmp_var_name)));
return child_scope->node;
}
@ -1781,12 +1802,14 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
}
// worst case
// c: ++expr
// zig: {
// zig: x: {
// zig: const _ref = &expr;
// zig: *_ref += 1;
// zig: *_ref
// zig: break :x *_ref
// zig: }
TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
child_scope->node->data.block.name = label_name;
// const _ref = &expr;
AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
@ -1805,11 +1828,10 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
trans_create_node_unsigned(c, 1));
child_scope->node->data.block.statements.append(assign_statement);
// *_ref
// break :x *_ref
AstNode *deref_expr = trans_create_node_prefix_op(c, PrefixOpDereference,
trans_create_node_symbol(c, ref_var_name));
child_scope->node->data.block.statements.append(deref_expr);
child_scope->node->data.block.last_statement_is_result_expression = true;
child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));
return child_scope->node;
}

View File

@ -8,7 +8,7 @@ pub fn ArrayList(comptime T: type) -> type {
}
pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
struct {
return struct {
const Self = this;
/// Use toSlice instead of slicing this directly, because if you don't
@ -20,11 +20,11 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
/// Deinitialize with `deinit` or use `toOwnedSlice`.
pub fn init(allocator: &Allocator) -> Self {
Self {
return Self {
.items = []align(A) T{},
.len = 0,
.allocator = allocator,
}
};
}
pub fn deinit(l: &Self) {
@ -107,7 +107,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
return null;
return self.pop();
}
}
};
}
test "basic ArrayList test" {

View File

@ -30,9 +30,9 @@ pub const Buffer = struct {
/// * ::replaceContentsBuffer
/// * ::resize
pub fn initNull(allocator: &Allocator) -> Buffer {
Buffer {
return Buffer {
.list = ArrayList(u8).init(allocator),
}
};
}
/// Must deinitialize with deinit.
@ -120,7 +120,7 @@ pub const Buffer = struct {
}
pub fn eql(self: &const Buffer, m: []const u8) -> bool {
mem.eql(u8, self.toSliceConst(), m)
return mem.eql(u8, self.toSliceConst(), m);
}
pub fn startsWith(self: &const Buffer, m: []const u8) -> bool {

View File

@ -221,11 +221,11 @@ pub const Builder = struct {
}
pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) -> Version {
Version {
return Version {
.major = major,
.minor = minor,
.patch = patch,
}
};
}
pub fn addCIncludePath(self: &Builder, path: []const u8) {
@ -432,16 +432,16 @@ pub const Builder = struct {
const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false;
const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") ?? false;
const mode = if (release_safe and !release_fast) {
const mode = if (release_safe and !release_fast)
builtin.Mode.ReleaseSafe
} else if (release_fast and !release_safe) {
else if (release_fast and !release_safe)
builtin.Mode.ReleaseFast
} else if (!release_fast and !release_safe) {
else if (!release_fast and !release_safe)
builtin.Mode.Debug
} else {
else x: {
warn("Both -Drelease-safe and -Drelease-fast specified");
self.markInvalidUserInput();
builtin.Mode.Debug
break :x builtin.Mode.Debug;
};
self.release_mode = mode;
return mode;
@ -506,7 +506,7 @@ pub const Builder = struct {
}
fn typeToEnum(comptime T: type) -> TypeId {
switch (@typeId(T)) {
return switch (@typeId(T)) {
builtin.TypeId.Int => TypeId.Int,
builtin.TypeId.Float => TypeId.Float,
builtin.TypeId.Bool => TypeId.Bool,
@ -515,7 +515,7 @@ pub const Builder = struct {
[]const []const u8 => TypeId.List,
else => @compileError("Unsupported type: " ++ @typeName(T)),
},
}
};
}
fn markInvalidUserInput(self: &Builder) {
@ -590,8 +590,7 @@ pub const Builder = struct {
return error.UncleanExit;
},
};
}
}
pub fn makePath(self: &Builder, path: []const u8) -> %void {
@ -662,13 +661,12 @@ pub const Builder = struct {
if (builtin.environ == builtin.Environ.msvc) {
return "cl.exe";
} else {
return os.getEnvVarOwned(self.allocator, "CC") %% |err| {
if (err == error.EnvironmentVariableNotFound) {
return os.getEnvVarOwned(self.allocator, "CC") %% |err|
if (err == error.EnvironmentVariableNotFound)
([]const u8)("cc")
} else {
debug.panic("Unable to get environment variable: {}", err);
}
};
else
debug.panic("Unable to get environment variable: {}", err)
;
}
}
@ -1079,11 +1077,10 @@ pub const LibExeObjStep = struct {
}
pub fn getOutputPath(self: &LibExeObjStep) -> []const u8 {
if (self.output_path) |output_path| {
return if (self.output_path) |output_path|
output_path
} else {
%%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename)
}
else
%%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename);
}
pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) {
@ -1096,11 +1093,10 @@ pub const LibExeObjStep = struct {
}
pub fn getOutputHPath(self: &LibExeObjStep) -> []const u8 {
if (self.output_h_path) |output_h_path| {
return if (self.output_h_path) |output_h_path|
output_h_path
} else {
%%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename)
}
else
%%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename);
}
pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) {
@ -1618,7 +1614,7 @@ pub const TestStep = struct {
pub fn init(builder: &Builder, root_src: []const u8) -> TestStep {
const step_name = builder.fmt("test {}", root_src);
TestStep {
return TestStep {
.step = Step.init(step_name, builder.allocator, make),
.builder = builder,
.root_src = root_src,
@ -1629,7 +1625,7 @@ pub const TestStep = struct {
.link_libs = BufSet.init(builder.allocator),
.target = Target { .Native = {} },
.exec_cmd_args = null,
}
};
}
pub fn setVerbose(self: &TestStep, value: bool) {
@ -1936,16 +1932,16 @@ pub const Step = struct {
done_flag: bool,
pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)->%void) -> Step {
Step {
return Step {
.name = name,
.makeFn = makeFn,
.dependencies = ArrayList(&Step).init(allocator),
.loop_flag = false,
.done_flag = false,
}
};
}
pub fn initNoOp(name: []const u8, allocator: &Allocator) -> Step {
init(name, allocator, makeNoOp)
return init(name, allocator, makeNoOp);
}
pub fn make(self: &Step) -> %void {

View File

@ -17,7 +17,7 @@ pub fn cmp(a: &const u8, b: &const u8) -> i8 {
return -1;
} else {
return 0;
};
}
}
pub fn toSliceConst(str: &const u8) -> []const u8 {

View File

@ -32,7 +32,7 @@ fn getStderrStream() -> %&io.OutStream {
const st = &stderr_file_out_stream.stream;
stderr_stream = st;
return st;
};
}
}
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
@ -52,9 +52,9 @@ pub fn assert(ok: bool) {
// we insert an explicit call to @panic instead of unreachable.
// TODO we should use `assertOrPanic` in tests and remove this logic.
if (builtin.is_test) {
@panic("assertion failure")
@panic("assertion failure");
} else {
unreachable // assertion failure
unreachable; // assertion failure
}
}
}
@ -175,7 +175,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
return_address, compile_unit_name);
},
else => return err,
};
}
}
},
builtin.ObjectFormat.coff => {
@ -357,7 +357,7 @@ const Die = struct {
FormValue.String => |value| value,
FormValue.StrPtr => |offset| getString(st, offset),
else => error.InvalidDebugInfo,
}
};
}
};
@ -403,7 +403,7 @@ const LineNumberProgram = struct {
pub fn init(is_stmt: bool, include_dirs: []const []const u8,
file_entries: &ArrayList(FileEntry), target_address: usize) -> LineNumberProgram
{
LineNumberProgram {
return LineNumberProgram {
.address = 0,
.file = 1,
.line = 1,
@ -421,7 +421,7 @@ const LineNumberProgram = struct {
.prev_is_stmt = undefined,
.prev_basic_block = undefined,
.prev_end_sequence = undefined,
}
};
}
pub fn checkLineMatch(self: &LineNumberProgram) -> %?LineInfo {
@ -430,14 +430,11 @@ const LineNumberProgram = struct {
return error.MissingDebugInfo;
} else if (self.prev_file - 1 >= self.file_entries.len) {
return error.InvalidDebugInfo;
} else {
&self.file_entries.items[self.prev_file - 1]
};
} else &self.file_entries.items[self.prev_file - 1];
const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {
return error.InvalidDebugInfo;
} else {
self.include_dirs[file_entry.dir_index]
};
} else self.include_dirs[file_entry.dir_index];
const file_name = %return os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
%defer self.file_entries.allocator.free(file_name);
return LineInfo {
@ -494,28 +491,21 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size:
}
fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue {
FormValue { .Const = Constant {
return FormValue { .Const = Constant {
.signed = signed,
.payload = %return readAllocBytes(allocator, in_stream, size),
}}
}};
}
fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 {
return if (is_64) {
%return in_stream.readIntLe(u64)
} else {
u64(%return in_stream.readIntLe(u32))
};
return if (is_64) %return in_stream.readIntLe(u64)
else u64(%return in_stream.readIntLe(u32)) ;
}
fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {
return if (@sizeOf(usize) == 4) {
u64(%return in_stream.readIntLe(u32))
} else if (@sizeOf(usize) == 8) {
%return in_stream.readIntLe(u64)
} else {
unreachable;
};
return if (@sizeOf(usize) == 4) u64(%return in_stream.readIntLe(u32))
else if (@sizeOf(usize) == 8) %return in_stream.readIntLe(u64)
else unreachable;
}
fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
@ -534,9 +524,9 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
DW.FORM_block => {
DW.FORM_block => x: {
const block_len = %return readULeb128(in_stream);
parseFormValueBlockLen(allocator, in_stream, block_len)
return parseFormValueBlockLen(allocator, in_stream, block_len);
},
DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1),
DW.FORM_data2 => parseFormValueConstant(allocator, in_stream, false, 2),
@ -545,7 +535,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_udata, DW.FORM_sdata => {
const block_len = %return readULeb128(in_stream);
const signed = form_id == DW.FORM_sdata;
parseFormValueConstant(allocator, in_stream, signed, block_len)
return parseFormValueConstant(allocator, in_stream, signed, block_len);
},
DW.FORM_exprloc => {
const size = %return readULeb128(in_stream);
@ -562,7 +552,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64),
DW.FORM_ref_udata => {
const ref_len = %return readULeb128(in_stream);
parseFormValueRefLen(allocator, in_stream, ref_len)
return parseFormValueRefLen(allocator, in_stream, ref_len);
},
DW.FORM_ref_addr => FormValue { .RefAddr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
@ -572,10 +562,10 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_strp => FormValue { .StrPtr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_indirect => {
const child_form_id = %return readULeb128(in_stream);
parseFormValue(allocator, in_stream, child_form_id, is_64)
return parseFormValue(allocator, in_stream, child_form_id, is_64);
},
else => error.InvalidDebugInfo,
}
};
}
fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
@ -852,11 +842,9 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
const version = %return in_stream.readInt(st.elf.endian, u16);
if (version < 2 or version > 5) return error.InvalidDebugInfo;
const debug_abbrev_offset = if (is_64) {
%return in_stream.readInt(st.elf.endian, u64)
} else {
%return in_stream.readInt(st.elf.endian, u32)
};
const debug_abbrev_offset =
if (is_64) %return in_stream.readInt(st.elf.endian, u64)
else %return in_stream.readInt(st.elf.endian, u32);
const address_size = %return in_stream.readByte();
if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
@ -872,28 +860,28 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
if (compile_unit_die.tag_id != DW.TAG_compile_unit)
return error.InvalidDebugInfo;
const pc_range = {
const pc_range = x: {
if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {
if (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {
const pc_end = switch (*high_pc_value) {
FormValue.Address => |value| value,
FormValue.Const => |value| {
FormValue.Const => |value| b: {
const offset = %return value.asUnsignedLe();
low_pc + offset
break :b (low_pc + offset);
},
else => return error.InvalidDebugInfo,
};
PcRange {
break :x PcRange {
.start = low_pc,
.end = pc_end,
}
};
} else {
null
break :x null;
}
} else |err| {
if (err != error.MissingDebugInfo)
return err;
null
break :x null;
}
};
@ -949,12 +937,12 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
const first_32_bits = %return in_stream.readIntLe(u32);
*is_64 = (first_32_bits == 0xffffffff);
return if (*is_64) {
%return in_stream.readIntLe(u64)
if (*is_64) {
return in_stream.readIntLe(u64);
} else {
if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
u64(first_32_bits)
};
return u64(first_32_bits);
}
}
fn readULeb128(in_stream: &io.InStream) -> %u64 {

View File

@ -2,15 +2,15 @@ const mem = @import("mem.zig");
const builtin = @import("builtin");
pub fn swapIfLe(comptime T: type, x: T) -> T {
swapIf(false, T, x)
return swapIf(false, T, x);
}
pub fn swapIfBe(comptime T: type, x: T) -> T {
swapIf(true, T, x)
return swapIf(true, T, x);
}
pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T {
if (builtin.endian == endian) swap(T, x) else x
return if (builtin.endian == endian) swap(T, x) else x;
}
pub fn swap(comptime T: type, x: T) -> T {

View File

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

View File

@ -251,11 +251,10 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
%return output(context, float_decimal.digits[0..1]);
%return output(context, ".");
if (float_decimal.digits.len > 1) {
const num_digits = if (@typeOf(value) == f32) {
const num_digits = if (@typeOf(value) == f32)
math.min(usize(9), float_decimal.digits.len)
} else {
float_decimal.digits.len
};
else
float_decimal.digits.len;
%return output(context, float_decimal.digits[1 .. num_digits]);
} else {
%return output(context, "0");

View File

@ -12,7 +12,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
comptime hash: fn(key: K)->u32,
comptime eql: fn(a: K, b: K)->bool) -> type
{
struct {
return struct {
entries: []Entry,
size: usize,
max_distance_from_start_index: usize,
@ -51,19 +51,19 @@ pub fn HashMap(comptime K: type, comptime V: type,
return entry;
}
}
unreachable // no next item
unreachable; // no next item
}
};
pub fn init(allocator: &Allocator) -> Self {
Self {
return Self {
.entries = []Entry{},
.allocator = allocator,
.size = 0,
.max_distance_from_start_index = 0,
// it doesn't actually matter what we set this to since we use wrapping integer arithmetic
.modification_count = undefined,
}
};
}
pub fn deinit(hm: &Self) {
@ -133,7 +133,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
entry.distance_from_start_index -= 1;
entry = next_entry;
}
unreachable // shifting everything in the table
unreachable; // shifting everything in the table
}}
return null;
}
@ -169,7 +169,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
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}) {
while (roll_over < hm.entries.len) : ({roll_over += 1; distance_from_start_index += 1;}) {
const index = (start_index + roll_over) % hm.entries.len;
const entry = &hm.entries[index];
@ -210,7 +210,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
};
return result;
}
unreachable // put into a full map
unreachable; // put into a full map
}
fn internalGet(hm: &Self, key: K) -> ?&Entry {
@ -228,7 +228,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
fn keyToIndex(hm: &Self, key: K) -> usize {
return usize(hash(key)) % hm.entries.len;
}
}
};
}
test "basicHashMapTest" {
@ -251,9 +251,9 @@ test "basicHashMapTest" {
}
fn hash_i32(x: i32) -> u32 {
@bitCast(u32, x)
return @bitCast(u32, x);
}
fn eql_i32(a: i32, b: i32) -> bool {
a == b
return a == b;
}

View File

@ -17,22 +17,21 @@ pub var c_allocator = Allocator {
};
fn cAlloc(self: &Allocator, n: usize, alignment: u29) -> %[]u8 {
if (c.malloc(usize(n))) |buf| {
return if (c.malloc(usize(n))) |buf|
@ptrCast(&u8, buf)[0..n]
} else {
error.OutOfMemory
}
else
error.OutOfMemory;
}
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {
if (new_size <= old_mem.len) {
old_mem[0..new_size]
return old_mem[0..new_size];
} else {
const old_ptr = @ptrCast(&c_void, old_mem.ptr);
if (c.realloc(old_ptr, usize(new_size))) |buf| {
@ptrCast(&u8, buf)[0..new_size]
return @ptrCast(&u8, buf)[0..new_size];
} else {
error.OutOfMemory
return error.OutOfMemory;
}
}
}

View File

@ -50,35 +50,32 @@ error Unseekable;
error EndOfFile;
pub fn getStdErr() -> %File {
const handle = if (is_windows) {
const handle = if (is_windows)
%return os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
} else if (is_posix) {
else if (is_posix)
system.STDERR_FILENO
} else {
unreachable
};
else
unreachable;
return File.openHandle(handle);
}
pub fn getStdOut() -> %File {
const handle = if (is_windows) {
const handle = if (is_windows)
%return os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
} else if (is_posix) {
else if (is_posix)
system.STDOUT_FILENO
} else {
unreachable
};
else
unreachable;
return File.openHandle(handle);
}
pub fn getStdIn() -> %File {
const handle = if (is_windows) {
const handle = if (is_windows)
%return os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
} else if (is_posix) {
else if (is_posix)
system.STDIN_FILENO
} else {
unreachable
};
else
unreachable;
return File.openHandle(handle);
}
@ -261,7 +258,7 @@ pub const File = struct {
system.EBADF => error.BadFd,
system.ENOMEM => error.SystemResources,
else => os.unexpectedErrorPosix(err),
}
};
}
return usize(stat.size);

View File

@ -5,7 +5,7 @@ const Allocator = mem.Allocator;
/// Generic doubly linked list.
pub fn LinkedList(comptime T: type) -> type {
struct {
return struct {
const Self = this;
/// Node inside the linked list wrapping the actual data.
@ -15,11 +15,11 @@ pub fn LinkedList(comptime T: type) -> type {
data: T,
pub fn init(data: &const T) -> Node {
Node {
return Node {
.prev = null,
.next = null,
.data = *data,
}
};
}
};
@ -32,11 +32,11 @@ pub fn LinkedList(comptime T: type) -> type {
/// Returns:
/// An empty linked list.
pub fn init() -> Self {
Self {
return Self {
.first = null,
.last = null,
.len = 0,
}
};
}
/// Insert a new node after an existing one.
@ -166,7 +166,7 @@ pub fn LinkedList(comptime T: type) -> type {
/// Returns:
/// A pointer to the new node.
pub fn allocateNode(list: &Self, allocator: &Allocator) -> %&Node {
allocator.create(Node)
return allocator.create(Node);
}
/// Deallocate a node.
@ -191,7 +191,7 @@ pub fn LinkedList(comptime T: type) -> type {
*node = Node.init(data);
return node;
}
}
};
}
test "basic linked list test" {

View File

@ -7,11 +7,11 @@ const assert = @import("../debug.zig").assert;
pub fn acos(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(acos32, x),
f64 => @inlineCall(acos64, x),
else => @compileError("acos not implemented for " ++ @typeName(T)),
}
};
}
fn r32(z: f32) -> f32 {
@ -22,7 +22,7 @@ fn r32(z: f32) -> f32 {
const p = z * (pS0 + z * (pS1 + z * pS2));
const q = 1.0 + z * qS1;
p / q
return p / q;
}
fn acos32(x: f32) -> f32 {
@ -69,7 +69,7 @@ fn acos32(x: f32) -> f32 {
const df = @bitCast(f32, jx & 0xFFFFF000);
const c = (z - df * df) / (s + df);
const w = r32(z) * s + c;
2 * (df + w)
return 2 * (df + w);
}
fn r64(z: f64) -> f64 {
@ -86,7 +86,7 @@ fn r64(z: f64) -> f64 {
const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
p / q
return p / q;
}
fn acos64(x: f64) -> f64 {
@ -138,7 +138,7 @@ fn acos64(x: f64) -> f64 {
const df = @bitCast(f64, jx & 0xFFFFFFFF00000000);
const c = (z - df * df) / (s + df);
const w = r64(z) * s + c;
2 * (df + w)
return 2 * (df + w);
}
test "math.acos" {

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn acosh(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(acosh32, x),
f64 => @inlineCall(acosh64, x),
else => @compileError("acosh not implemented for " ++ @typeName(T)),
}
};
}
// acosh(x) = log(x + sqrt(x * x - 1))
@ -23,15 +23,15 @@ fn acosh32(x: f32) -> f32 {
// |x| < 2, invalid if x < 1 or nan
if (i < 0x3F800000 + (1 << 23)) {
math.log1p(x - 1 + math.sqrt((x - 1) * (x - 1) + 2 * (x - 1)))
return math.log1p(x - 1 + math.sqrt((x - 1) * (x - 1) + 2 * (x - 1)));
}
// |x| < 0x1p12
else if (i < 0x3F800000 + (12 << 23)) {
math.ln(2 * x - 1 / (x + math.sqrt(x * x - 1)))
return math.ln(2 * x - 1 / (x + math.sqrt(x * x - 1)));
}
// |x| >= 0x1p12
else {
math.ln(x) + 0.693147180559945309417232121458176568
return math.ln(x) + 0.693147180559945309417232121458176568;
}
}
@ -41,15 +41,15 @@ fn acosh64(x: f64) -> f64 {
// |x| < 2, invalid if x < 1 or nan
if (e < 0x3FF + 1) {
math.log1p(x - 1 + math.sqrt((x - 1) * (x - 1) + 2 * (x - 1)))
return math.log1p(x - 1 + math.sqrt((x - 1) * (x - 1) + 2 * (x - 1)));
}
// |x| < 0x1p26
else if (e < 0x3FF + 26) {
math.ln(2 * x - 1 / (x + math.sqrt(x * x - 1)))
return math.ln(2 * x - 1 / (x + math.sqrt(x * x - 1)));
}
// |x| >= 0x1p26 or nan
else {
math.ln(x) + 0.693147180559945309417232121458176568
return math.ln(x) + 0.693147180559945309417232121458176568;
}
}

View File

@ -8,11 +8,11 @@ const assert = @import("../debug.zig").assert;
pub fn asin(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(asin32, x),
f64 => @inlineCall(asin64, x),
else => @compileError("asin not implemented for " ++ @typeName(T)),
}
};
}
fn r32(z: f32) -> f32 {
@ -23,7 +23,7 @@ fn r32(z: f32) -> f32 {
const p = z * (pS0 + z * (pS1 + z * pS2));
const q = 1.0 + z * qS1;
p / q
return p / q;
}
fn asin32(x: f32) -> f32 {
@ -58,9 +58,9 @@ fn asin32(x: f32) -> f32 {
const fx = pio2 - 2 * (s + s * r32(z));
if (hx >> 31 != 0) {
-fx
return -fx;
} else {
fx
return fx;
}
}
@ -78,7 +78,7 @@ fn r64(z: f64) -> f64 {
const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
p / q
return p / q;
}
fn asin64(x: f64) -> f64 {
@ -119,7 +119,7 @@ fn asin64(x: f64) -> f64 {
// |x| > 0.975
if (ix >= 0x3FEF3333) {
fx = pio2_hi - 2 * (s + s * r)
fx = pio2_hi - 2 * (s + s * r);
} else {
const jx = @bitCast(u64, s);
const df = @bitCast(f64, jx & 0xFFFFFFFF00000000);
@ -128,9 +128,9 @@ fn asin64(x: f64) -> f64 {
}
if (hx >> 31 != 0) {
-fx
return -fx;
} else {
fx
return fx;
}
}

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn asinh(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(asinh32, x),
f64 => @inlineCall(asinh64, x),
else => @compileError("asinh not implemented for " ++ @typeName(T)),
}
};
}
// asinh(x) = sign(x) * log(|x| + sqrt(x * x + 1)) ~= x - x^3/6 + o(x^5)
@ -46,7 +46,7 @@ fn asinh32(x: f32) -> f32 {
math.forceEval(x + 0x1.0p120);
}
if (s != 0) -rx else rx
return if (s != 0) -rx else rx;
}
fn asinh64(x: f64) -> f64 {
@ -77,7 +77,7 @@ fn asinh64(x: f64) -> f64 {
math.forceEval(x + 0x1.0p120);
}
if (s != 0) -rx else rx
return if (s != 0) -rx else rx;
}
test "math.asinh" {

View File

@ -8,11 +8,11 @@ const assert = @import("../debug.zig").assert;
pub fn atan(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(atan32, x),
f64 => @inlineCall(atan64, x),
else => @compileError("atan not implemented for " ++ @typeName(T)),
}
};
}
fn atan32(x_: f32) -> f32 {
@ -100,10 +100,10 @@ fn atan32(x_: f32) -> f32 {
const s2 = w * (aT[1] + w * aT[3]);
if (id == null) {
x - x * (s1 + s2)
return x - x * (s1 + s2);
} else {
const zz = atanhi[??id] - ((x * (s1 + s2) - atanlo[??id]) - x);
if (sign != 0) -zz else zz
return if (sign != 0) -zz else zz;
}
}
@ -199,10 +199,10 @@ fn atan64(x_: f64) -> f64 {
const s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
if (id == null) {
x - x * (s1 + s2)
return x - x * (s1 + s2);
} else {
const zz = atanhi[??id] - ((x * (s1 + s2) - atanlo[??id]) - x);
if (sign != 0) -zz else zz
return if (sign != 0) -zz else zz;
}
}

View File

@ -22,11 +22,11 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
fn atan2(comptime T: type, x: T, y: T) -> T {
switch (T) {
return switch (T) {
f32 => @inlineCall(atan2_32, x, y),
f64 => @inlineCall(atan2_64, x, y),
else => @compileError("atan2 not implemented for " ++ @typeName(T)),
}
};
}
fn atan2_32(y: f32, x: f32) -> f32 {
@ -97,11 +97,11 @@ fn atan2_32(y: f32, x: f32) -> f32 {
}
// z = atan(|y / x|) with correct underflow
var z = {
var z = z: {
if ((m & 2) != 0 and iy + (26 << 23) < ix) {
0.0
break :z 0.0;
} else {
math.atan(math.fabs(y / x))
break :z math.atan(math.fabs(y / x));
}
};
@ -187,11 +187,11 @@ fn atan2_64(y: f64, x: f64) -> f64 {
}
// z = atan(|y / x|) with correct underflow
var z = {
var z = z: {
if ((m & 2) != 0 and iy +% (64 << 20) < ix) {
0.0
break :z 0.0;
} else {
math.atan(math.fabs(y / x))
break :z math.atan(math.fabs(y / x));
}
};

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn atanh(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(atanh_32, x),
f64 => @inlineCall(atanh_64, x),
else => @compileError("atanh not implemented for " ++ @typeName(T)),
}
};
}
// atanh(x) = log((1 + x) / (1 - x)) / 2 = log1p(2x / (1 - x)) / 2 ~= x + x^3 / 3 + o(x^5)
@ -32,7 +32,7 @@ fn atanh_32(x: f32) -> f32 {
if (u < 0x3F800000 - (32 << 23)) {
// underflow
if (u < (1 << 23)) {
math.forceEval(y * y)
math.forceEval(y * y);
}
}
// |x| < 0.5
@ -43,7 +43,7 @@ fn atanh_32(x: f32) -> f32 {
y = 0.5 * math.log1p(2 * (y / (1 - y)));
}
if (s != 0) -y else y
return if (s != 0) -y else y;
}
fn atanh_64(x: f64) -> f64 {
@ -72,7 +72,7 @@ fn atanh_64(x: f64) -> f64 {
y = 0.5 * math.log1p(2 * (y / (1 - y)));
}
if (s != 0) -y else y
return if (s != 0) -y else y;
}
test "math.atanh" {

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn cbrt(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(cbrt32, x),
f64 => @inlineCall(cbrt64, x),
else => @compileError("cbrt not implemented for " ++ @typeName(T)),
}
};
}
fn cbrt32(x: f32) -> f32 {
@ -53,7 +53,7 @@ fn cbrt32(x: f32) -> f32 {
r = t * t * t;
t = t * (f64(x) + x + r) / (x + r + r);
f32(t)
return f32(t);
}
fn cbrt64(x: f64) -> f64 {
@ -109,7 +109,7 @@ fn cbrt64(x: f64) -> f64 {
var w = t + t;
q = (q - t) / (w + q);
t + t * q
return t + t * q;
}
test "math.cbrt" {

View File

@ -10,11 +10,11 @@ const assert = @import("../debug.zig").assert;
pub fn ceil(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(ceil32, x),
f64 => @inlineCall(ceil64, x),
else => @compileError("ceil not implemented for " ++ @typeName(T)),
}
};
}
fn ceil32(x: f32) -> f32 {
@ -39,13 +39,13 @@ fn ceil32(x: f32) -> f32 {
u += m;
}
u &= ~m;
@bitCast(f32, u)
return @bitCast(f32, u);
} else {
math.forceEval(x + 0x1.0p120);
if (u >> 31 != 0) {
return -0.0;
} else {
1.0
return 1.0;
}
}
}
@ -70,14 +70,14 @@ fn ceil64(x: f64) -> f64 {
if (e <= 0x3FF-1) {
math.forceEval(y);
if (u >> 63 != 0) {
return -0.0; // Compiler requires return.
return -0.0;
} else {
1.0
return 1.0;
}
} else if (y < 0) {
x + y + 1
return x + y + 1;
} else {
x + y
return x + y;
}
}

View File

@ -2,11 +2,11 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
pub fn copysign(comptime T: type, x: T, y: T) -> T {
switch (T) {
return switch (T) {
f32 => @inlineCall(copysign32, x, y),
f64 => @inlineCall(copysign64, x, y),
else => @compileError("copysign not implemented for " ++ @typeName(T)),
}
};
}
fn copysign32(x: f32, y: f32) -> f32 {
@ -15,7 +15,7 @@ fn copysign32(x: f32, y: f32) -> f32 {
const h1 = ux & (@maxValue(u32) / 2);
const h2 = uy & (u32(1) << 31);
@bitCast(f32, h1 | h2)
return @bitCast(f32, h1 | h2);
}
fn copysign64(x: f64, y: f64) -> f64 {
@ -24,7 +24,7 @@ fn copysign64(x: f64, y: f64) -> f64 {
const h1 = ux & (@maxValue(u64) / 2);
const h2 = uy & (u64(1) << 63);
@bitCast(f64, h1 | h2)
return @bitCast(f64, h1 | h2);
}
test "math.copysign" {

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn cos(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(cos32, x),
f64 => @inlineCall(cos64, x),
else => @compileError("cos not implemented for " ++ @typeName(T)),
}
};
}
// sin polynomial coefficients
@ -73,18 +73,18 @@ fn cos32(x_: f32) -> f32 {
const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
const w = z * z;
const r = {
const r = r: {
if (j == 1 or j == 2) {
z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))))
break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
} else {
1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))))
break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
}
};
if (sign) {
-r
return -r;
} else {
r
return r;
}
}
@ -124,18 +124,18 @@ fn cos64(x_: f64) -> f64 {
const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
const w = z * z;
const r = {
const r = r: {
if (j == 1 or j == 2) {
z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))))
break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
} else {
1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))))
break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
}
};
if (sign) {
-r
return -r;
} else {
r
return r;
}
}

View File

@ -11,11 +11,11 @@ const assert = @import("../debug.zig").assert;
pub fn cosh(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(cosh32, x),
f64 => @inlineCall(cosh64, x),
else => @compileError("cosh not implemented for " ++ @typeName(T)),
}
};
}
// cosh(x) = (exp(x) + 1 / exp(x)) / 2
@ -43,7 +43,7 @@ fn cosh32(x: f32) -> f32 {
}
// |x| > log(FLT_MAX) or nan
expo2(ax)
return expo2(ax);
}
fn cosh64(x: f64) -> f64 {
@ -76,7 +76,7 @@ fn cosh64(x: f64) -> f64 {
}
// |x| > log(CBL_MAX) or nan
expo2(ax)
return expo2(ax);
}
test "math.cosh" {

View File

@ -8,11 +8,11 @@ const assert = @import("../debug.zig").assert;
pub fn exp(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(exp32, x),
f64 => @inlineCall(exp64, x),
else => @compileError("exp not implemented for " ++ @typeName(T)),
}
};
}
fn exp32(x_: f32) -> f32 {
@ -86,9 +86,9 @@ fn exp32(x_: f32) -> f32 {
const y = 1 + (x * c / (2 - c) - lo + hi);
if (k == 0) {
y
return y;
} else {
math.scalbn(y, k)
return math.scalbn(y, k);
}
}
@ -172,9 +172,9 @@ fn exp64(x_: f64) -> f64 {
const y = 1 + (x * c / (2 - c) - lo + hi);
if (k == 0) {
y
return y;
} else {
math.scalbn(y, k)
return math.scalbn(y, k);
}
}

View File

@ -8,11 +8,11 @@ const assert = @import("../debug.zig").assert;
pub fn exp2(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(exp2_32, x),
f64 => @inlineCall(exp2_64, x),
else => @compileError("exp2 not implemented for " ++ @typeName(T)),
}
};
}
const exp2ft = []const f64 {
@ -88,7 +88,7 @@ fn exp2_32(x: f32) -> f32 {
var r: f64 = exp2ft[i0];
const t: f64 = r * z;
r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
f32(r * uk)
return f32(r * uk);
}
const exp2dt = []f64 {
@ -414,7 +414,7 @@ fn exp2_64(x: f64) -> f64 {
z -= exp2dt[2 * i0 + 1];
const r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
math.scalbn(r, ik)
return math.scalbn(r, ik);
}
test "math.exp2" {

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn expm1(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(expm1_32, x),
f64 => @inlineCall(expm1_64, x),
else => @compileError("exp1m not implemented for " ++ @typeName(T)),
}
};
}
fn expm1_32(x_: f32) -> f32 {

View File

@ -2,11 +2,11 @@ const math = @import("index.zig");
pub fn expo2(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => expo2f(x),
f64 => expo2d(x),
else => @compileError("expo2 not implemented for " ++ @typeName(T)),
}
};
}
fn expo2f(x: f32) -> f32 {
@ -15,7 +15,7 @@ fn expo2f(x: f32) -> f32 {
const u = (0x7F + k / 2) << 23;
const scale = @bitCast(f32, u);
math.exp(x - kln2) * scale * scale
return math.exp(x - kln2) * scale * scale;
}
fn expo2d(x: f64) -> f64 {
@ -24,5 +24,5 @@ fn expo2d(x: f64) -> f64 {
const u = (0x3FF + k / 2) << 20;
const scale = @bitCast(f64, u64(u) << 32);
math.exp(x - kln2) * scale * scale
return math.exp(x - kln2) * scale * scale;
}

View File

@ -8,23 +8,23 @@ const assert = @import("../debug.zig").assert;
pub fn fabs(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(fabs32, x),
f64 => @inlineCall(fabs64, x),
else => @compileError("fabs not implemented for " ++ @typeName(T)),
}
};
}
fn fabs32(x: f32) -> f32 {
var u = @bitCast(u32, x);
u &= 0x7FFFFFFF;
@bitCast(f32, u)
return @bitCast(f32, u);
}
fn fabs64(x: f64) -> f64 {
var u = @bitCast(u64, x);
u &= @maxValue(u64) >> 1;
@bitCast(f64, u)
return @bitCast(f64, u);
}
test "math.fabs" {

View File

@ -10,11 +10,11 @@ const math = @import("index.zig");
pub fn floor(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(floor32, x),
f64 => @inlineCall(floor64, x),
else => @compileError("floor not implemented for " ++ @typeName(T)),
}
};
}
fn floor32(x: f32) -> f32 {
@ -40,13 +40,13 @@ fn floor32(x: f32) -> f32 {
if (u >> 31 != 0) {
u += m;
}
@bitCast(f32, u & ~m)
return @bitCast(f32, u & ~m);
} else {
math.forceEval(x + 0x1.0p120);
if (u >> 31 == 0) {
return 0.0; // Compiler requires return
return 0.0;
} else {
-1.0
return -1.0;
}
}
}
@ -71,14 +71,14 @@ fn floor64(x: f64) -> f64 {
if (e <= 0x3FF-1) {
math.forceEval(y);
if (u >> 63 != 0) {
return -1.0; // Compiler requires return.
return -1.0;
} else {
0.0
return 0.0;
}
} else if (y > 0) {
x + y - 1
return x + y - 1;
} else {
x + y
return x + y;
}
}

View File

@ -2,11 +2,11 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {
switch (T) {
return switch (T) {
f32 => @inlineCall(fma32, x, y, z),
f64 => @inlineCall(fma64, x, y ,z),
else => @compileError("fma not implemented for " ++ @typeName(T)),
}
};
}
fn fma32(x: f32, y: f32, z: f32) -> f32 {
@ -16,10 +16,10 @@ fn fma32(x: f32, y: f32, z: f32) -> f32 {
const e = (u >> 52) & 0x7FF;
if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or xy_z - xy == z) {
f32(xy_z)
return f32(xy_z);
} else {
// TODO: Handle inexact case with double-rounding
f32(xy_z)
return f32(xy_z);
}
}
@ -64,9 +64,9 @@ fn fma64(x: f64, y: f64, z: f64) -> f64 {
const adj = add_adjusted(r.lo, xy.lo);
if (spread + math.ilogb(r.hi) > -1023) {
math.scalbn(r.hi + adj, spread)
return math.scalbn(r.hi + adj, spread);
} else {
add_and_denorm(r.hi, adj, spread)
return add_and_denorm(r.hi, adj, spread);
}
}
@ -77,7 +77,7 @@ fn dd_add(a: f64, b: f64) -> dd {
ret.hi = a + b;
const s = ret.hi - a;
ret.lo = (a - (ret.hi - s)) + (b - s);
ret
return ret;
}
fn dd_mul(a: f64, b: f64) -> dd {
@ -99,7 +99,7 @@ fn dd_mul(a: f64, b: f64) -> dd {
ret.hi = p + q;
ret.lo = p - ret.hi + q + la * lb;
ret
return ret;
}
fn add_adjusted(a: f64, b: f64) -> f64 {
@ -113,7 +113,7 @@ fn add_adjusted(a: f64, b: f64) -> f64 {
sum.hi = @bitCast(f64, uhii);
}
}
sum.hi
return sum.hi;
}
fn add_and_denorm(a: f64, b: f64, scale: i32) -> f64 {
@ -127,7 +127,7 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) -> f64 {
sum.hi = @bitCast(f64, uhii);
}
}
math.scalbn(sum.hi, scale)
return math.scalbn(sum.hi, scale);
}
test "math.fma" {

View File

@ -8,21 +8,21 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
fn frexp_result(comptime T: type) -> type {
struct {
return struct {
significand: T,
exponent: i32,
}
};
}
pub const frexp32_result = frexp_result(f32);
pub const frexp64_result = frexp_result(f64);
pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(frexp32, x),
f64 => @inlineCall(frexp64, x),
else => @compileError("frexp not implemented for " ++ @typeName(T)),
}
};
}
fn frexp32(x: f32) -> frexp32_result {
@ -59,7 +59,7 @@ fn frexp32(x: f32) -> frexp32_result {
y &= 0x807FFFFF;
y |= 0x3F000000;
result.significand = @bitCast(f32, y);
result
return result;
}
fn frexp64(x: f64) -> frexp64_result {
@ -96,7 +96,7 @@ fn frexp64(x: f64) -> frexp64_result {
y &= 0x800FFFFFFFFFFFFF;
y |= 0x3FE0000000000000;
result.significand = @bitCast(f64, y);
result
return result;
}
test "math.frexp" {

View File

@ -9,11 +9,11 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
pub fn hypot(comptime T: type, x: T, y: T) -> T {
switch (T) {
return switch (T) {
f32 => @inlineCall(hypot32, x, y),
f64 => @inlineCall(hypot64, x, y),
else => @compileError("hypot not implemented for " ++ @typeName(T)),
}
};
}
fn hypot32(x: f32, y: f32) -> f32 {
@ -48,7 +48,7 @@ fn hypot32(x: f32, y: f32) -> f32 {
yy *= 0x1.0p-90;
}
z * math.sqrt(f32(f64(x) * x + f64(y) * y))
return z * math.sqrt(f32(f64(x) * x + f64(y) * y));
}
fn sq(hi: &f64, lo: &f64, x: f64) {
@ -109,7 +109,7 @@ fn hypot64(x: f64, y: f64) -> f64 {
sq(&hx, &lx, x);
sq(&hy, &ly, y);
z * math.sqrt(ly + lx + hy + hx)
return z * math.sqrt(ly + lx + hy + hx);
}
test "math.hypot" {

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn ilogb(x: var) -> i32 {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(ilogb32, x),
f64 => @inlineCall(ilogb64, x),
else => @compileError("ilogb not implemented for " ++ @typeName(T)),
}
};
}
// NOTE: Should these be exposed publically?
@ -53,7 +53,7 @@ fn ilogb32(x: f32) -> i32 {
}
}
e - 0x7F
return e - 0x7F;
}
fn ilogb64(x: f64) -> i32 {
@ -88,7 +88,7 @@ fn ilogb64(x: f64) -> i32 {
}
}
e - 0x3FF
return e - 0x3FF;
}
test "math.ilogb" {

View File

@ -36,7 +36,7 @@ pub const inf = @import("inf.zig").inf;
pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) -> bool {
assert(@typeId(T) == TypeId.Float);
fabs(x - y) < epsilon
return fabs(x - y) < epsilon;
}
// TODO: Hide the following in an internal module.
@ -175,7 +175,7 @@ test "math" {
pub fn min(x: var, y: var) -> @typeOf(x + y) {
if (x < y) x else y
return if (x < y) x else y;
}
test "math.min" {
@ -183,7 +183,7 @@ test "math.min" {
}
pub fn max(x: var, y: var) -> @typeOf(x + y) {
if (x > y) x else y
return if (x > y) x else y;
}
test "math.max" {
@ -193,19 +193,19 @@ test "math.max" {
error Overflow;
pub fn mul(comptime T: type, a: T, b: T) -> %T {
var answer: T = undefined;
if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
error Overflow;
pub fn add(comptime T: type, a: T, b: T) -> %T {
var answer: T = undefined;
if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
error Overflow;
pub fn sub(comptime T: type, a: T, b: T) -> %T {
var answer: T = undefined;
if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
pub fn negate(x: var) -> %@typeOf(x) {
@ -215,7 +215,7 @@ pub fn negate(x: var) -> %@typeOf(x) {
error Overflow;
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) -> %T {
var answer: T = undefined;
if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer
return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
}
/// Shifts left. Overflowed bits are truncated.
@ -267,7 +267,7 @@ test "math.shr" {
}
pub fn Log2Int(comptime T: type) -> type {
@IntType(false, log2(T.bit_count))
return @IntType(false, log2(T.bit_count));
}
test "math overflow functions" {

View File

@ -2,9 +2,9 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
pub fn inf(comptime T: type) -> T {
switch (T) {
return switch (T) {
f32 => @bitCast(f32, math.inf_u32),
f64 => @bitCast(f64, math.inf_u64),
else => @compileError("inf not implemented for " ++ @typeName(T)),
}
};
}

View File

@ -6,11 +6,11 @@ pub fn isFinite(x: var) -> bool {
switch (T) {
f32 => {
const bits = @bitCast(u32, x);
bits & 0x7FFFFFFF < 0x7F800000
return bits & 0x7FFFFFFF < 0x7F800000;
},
f64 => {
const bits = @bitCast(u64, x);
bits & (@maxValue(u64) >> 1) < (0x7FF << 52)
return bits & (@maxValue(u64) >> 1) < (0x7FF << 52);
},
else => {
@compileError("isFinite not implemented for " ++ @typeName(T));

View File

@ -6,11 +6,11 @@ pub fn isInf(x: var) -> bool {
switch (T) {
f32 => {
const bits = @bitCast(u32, x);
bits & 0x7FFFFFFF == 0x7F800000
return bits & 0x7FFFFFFF == 0x7F800000;
},
f64 => {
const bits = @bitCast(u64, x);
bits & (@maxValue(u64) >> 1) == (0x7FF << 52)
return bits & (@maxValue(u64) >> 1) == (0x7FF << 52);
},
else => {
@compileError("isInf not implemented for " ++ @typeName(T));
@ -22,10 +22,10 @@ pub fn isPositiveInf(x: var) -> bool {
const T = @typeOf(x);
switch (T) {
f32 => {
@bitCast(u32, x) == 0x7F800000
return @bitCast(u32, x) == 0x7F800000;
},
f64 => {
@bitCast(u64, x) == 0x7FF << 52
return @bitCast(u64, x) == 0x7FF << 52;
},
else => {
@compileError("isPositiveInf not implemented for " ++ @typeName(T));
@ -37,10 +37,10 @@ pub fn isNegativeInf(x: var) -> bool {
const T = @typeOf(x);
switch (T) {
f32 => {
@bitCast(u32, x) == 0xFF800000
return @bitCast(u32, x) == 0xFF800000;
},
f64 => {
@bitCast(u64, x) == 0xFFF << 52
return @bitCast(u64, x) == 0xFFF << 52;
},
else => {
@compileError("isNegativeInf not implemented for " ++ @typeName(T));

View File

@ -6,11 +6,11 @@ pub fn isNan(x: var) -> bool {
switch (T) {
f32 => {
const bits = @bitCast(u32, x);
bits & 0x7FFFFFFF > 0x7F800000
return bits & 0x7FFFFFFF > 0x7F800000;
},
f64 => {
const bits = @bitCast(u64, x);
(bits & (@maxValue(u64) >> 1)) > (u64(0x7FF) << 52)
return (bits & (@maxValue(u64) >> 1)) > (u64(0x7FF) << 52);
},
else => {
@compileError("isNan not implemented for " ++ @typeName(T));
@ -21,7 +21,7 @@ pub fn isNan(x: var) -> bool {
// Note: A signalling nan is identical to a standard right now by may have a different bit
// representation in the future when required.
pub fn isSignalNan(x: var) -> bool {
isNan(x)
return isNan(x);
}
test "math.isNan" {

View File

@ -6,11 +6,11 @@ pub fn isNormal(x: var) -> bool {
switch (T) {
f32 => {
const bits = @bitCast(u32, x);
(bits + 0x00800000) & 0x7FFFFFFF >= 0x01000000
return (bits + 0x00800000) & 0x7FFFFFFF >= 0x01000000;
},
f64 => {
const bits = @bitCast(u64, x);
(bits + (1 << 52)) & (@maxValue(u64) >> 1) >= (1 << 53)
return (bits + (1 << 52)) & (@maxValue(u64) >> 1) >= (1 << 53);
},
else => {
@compileError("isNormal not implemented for " ++ @typeName(T));

View File

@ -14,7 +14,7 @@ pub fn ln(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
return @typeOf(1.0)(ln_64(x))
return @typeOf(1.0)(ln_64(x));
},
TypeId.Float => {
return switch (T) {
@ -84,7 +84,7 @@ pub fn ln_32(x_: f32) -> f32 {
const hfsq = 0.5 * f * f;
const dk = f32(k);
s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
}
pub fn ln_64(x_: f64) -> f64 {
@ -116,7 +116,7 @@ pub fn ln_64(x_: f64) -> f64 {
// subnormal, scale x
k -= 54;
x *= 0x1.0p54;
hx = u32(@bitCast(u64, ix) >> 32)
hx = u32(@bitCast(u64, ix) >> 32);
}
else if (hx >= 0x7FF00000) {
return x;
@ -142,7 +142,7 @@ pub fn ln_64(x_: f64) -> f64 {
const R = t2 + t1;
const dk = f64(k);
s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
}
test "math.ln" {

View File

@ -29,7 +29,7 @@ pub fn log(comptime T: type, base: T, x: T) -> T {
f32 => return f32(math.ln(f64(x)) / math.ln(f64(base))),
f64 => return math.ln(x) / math.ln(f64(base)),
else => @compileError("log not implemented for " ++ @typeName(T)),
};
}
},
else => {

View File

@ -14,7 +14,7 @@ pub fn log10(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
return @typeOf(1.0)(log10_64(x))
return @typeOf(1.0)(log10_64(x));
},
TypeId.Float => {
return switch (T) {
@ -90,7 +90,7 @@ pub fn log10_32(x_: f32) -> f32 {
const lo = f - hi - hfsq + s * (hfsq + R);
const dk = f32(k);
dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi
return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
}
pub fn log10_64(x_: f64) -> f64 {
@ -124,7 +124,7 @@ pub fn log10_64(x_: f64) -> f64 {
// subnormal, scale x
k -= 54;
x *= 0x1.0p54;
hx = u32(@bitCast(u64, x) >> 32)
hx = u32(@bitCast(u64, x) >> 32);
}
else if (hx >= 0x7FF00000) {
return x;
@ -167,7 +167,7 @@ pub fn log10_64(x_: f64) -> f64 {
val_lo += (y - ww) + val_hi;
val_hi = ww;
val_lo + val_hi
return val_lo + val_hi;
}
test "math.log10" {

View File

@ -11,11 +11,11 @@ const assert = @import("../debug.zig").assert;
pub fn log1p(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(log1p_32, x),
f64 => @inlineCall(log1p_64, x),
else => @compileError("log1p not implemented for " ++ @typeName(T)),
}
};
}
fn log1p_32(x: f32) -> f32 {
@ -91,7 +91,7 @@ fn log1p_32(x: f32) -> f32 {
const hfsq = 0.5 * f * f;
const dk = f32(k);
s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi
return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
}
fn log1p_64(x: f64) -> f64 {
@ -172,7 +172,7 @@ fn log1p_64(x: f64) -> f64 {
const R = t2 + t1;
const dk = f64(k);
s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi
return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
}
test "math.log1p" {

View File

@ -14,7 +14,7 @@ pub fn log2(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
return @typeOf(1.0)(log2_64(x))
return @typeOf(1.0)(log2_64(x));
},
TypeId.Float => {
return switch (T) {
@ -26,7 +26,7 @@ pub fn log2(x: var) -> @typeOf(x) {
TypeId.IntLiteral => comptime {
var result = 0;
var x_shifted = x;
while ({x_shifted >>= 1; x_shifted != 0}) : (result += 1) {}
while (b: {x_shifted >>= 1; break :b x_shifted != 0;}) : (result += 1) {}
return result;
},
TypeId.Int => {
@ -94,7 +94,7 @@ pub fn log2_32(x_: f32) -> f32 {
u &= 0xFFFFF000;
hi = @bitCast(f32, u);
const lo = f - hi - hfsq + s * (hfsq + R);
(lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k)
return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k);
}
pub fn log2_64(x_: f64) -> f64 {
@ -165,7 +165,7 @@ pub fn log2_64(x_: f64) -> f64 {
val_lo += (y - ww) + val_hi;
val_hi = ww;
val_lo + val_hi
return val_lo + val_hi;
}
test "math.log2" {

View File

@ -7,21 +7,21 @@ const math = @import("index.zig");
const assert = @import("../debug.zig").assert;
fn modf_result(comptime T: type) -> type {
struct {
return struct {
fpart: T,
ipart: T,
}
};
}
pub const modf32_result = modf_result(f32);
pub const modf64_result = modf_result(f64);
pub fn modf(x: var) -> modf_result(@typeOf(x)) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(modf32, x),
f64 => @inlineCall(modf64, x),
else => @compileError("modf not implemented for " ++ @typeName(T)),
}
};
}
fn modf32(x: f32) -> modf32_result {
@ -66,7 +66,7 @@ fn modf32(x: f32) -> modf32_result {
const uf = @bitCast(f32, u & ~mask);
result.ipart = uf;
result.fpart = x - uf;
result
return result;
}
fn modf64(x: f64) -> modf64_result {
@ -110,7 +110,7 @@ fn modf64(x: f64) -> modf64_result {
const uf = @bitCast(f64, u & ~mask);
result.ipart = uf;
result.fpart = x - uf;
result
return result;
}
test "math.modf" {

View File

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

View File

@ -166,12 +166,12 @@ pub fn pow(comptime T: type, x: T, y: T) -> T {
ae = -ae;
}
math.scalbn(a1, ae)
return math.scalbn(a1, ae);
}
fn isOddInteger(x: f64) -> bool {
const r = math.modf(x);
r.fpart == 0.0 and i64(r.ipart) & 1 == 1
return r.fpart == 0.0 and i64(r.ipart) & 1 == 1;
}
test "math.pow" {

View File

@ -10,11 +10,11 @@ const math = @import("index.zig");
pub fn round(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(round32, x),
f64 => @inlineCall(round64, x),
else => @compileError("round not implemented for " ++ @typeName(T)),
}
};
}
fn round32(x_: f32) -> f32 {
@ -48,9 +48,9 @@ fn round32(x_: f32) -> f32 {
}
if (u >> 31 != 0) {
-y
return -y;
} else {
y
return y;
}
}
@ -85,9 +85,9 @@ fn round64(x_: f64) -> f64 {
}
if (u >> 63 != 0) {
-y
return -y;
} else {
y
return y;
}
}

View File

@ -3,11 +3,11 @@ const assert = @import("../debug.zig").assert;
pub fn scalbn(x: var, n: i32) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(scalbn32, x, n),
f64 => @inlineCall(scalbn64, x, n),
else => @compileError("scalbn not implemented for " ++ @typeName(T)),
}
};
}
fn scalbn32(x: f32, n_: i32) -> f32 {
@ -37,7 +37,7 @@ fn scalbn32(x: f32, n_: i32) -> f32 {
}
const u = u32(n +% 0x7F) << 23;
y * @bitCast(f32, u)
return y * @bitCast(f32, u);
}
fn scalbn64(x: f64, n_: i32) -> f64 {
@ -67,7 +67,7 @@ fn scalbn64(x: f64, n_: i32) -> f64 {
}
const u = u64(n +% 0x3FF) << 52;
y * @bitCast(f64, u)
return y * @bitCast(f64, u);
}
test "math.scalbn" {

View File

@ -3,21 +3,21 @@ const assert = @import("../debug.zig").assert;
pub fn signbit(x: var) -> bool {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(signbit32, x),
f64 => @inlineCall(signbit64, x),
else => @compileError("signbit not implemented for " ++ @typeName(T)),
}
};
}
fn signbit32(x: f32) -> bool {
const bits = @bitCast(u32, x);
bits >> 31 != 0
return bits >> 31 != 0;
}
fn signbit64(x: f64) -> bool {
const bits = @bitCast(u64, x);
bits >> 63 != 0
return bits >> 63 != 0;
}
test "math.signbit" {

View File

@ -10,11 +10,11 @@ const assert = @import("../debug.zig").assert;
pub fn sin(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(sin32, x),
f64 => @inlineCall(sin64, x),
else => @compileError("sin not implemented for " ++ @typeName(T)),
}
};
}
// sin polynomial coefficients
@ -75,18 +75,18 @@ fn sin32(x_: f32) -> f32 {
const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
const w = z * z;
const r = {
const r = r: {
if (j == 1 or j == 2) {
1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))))
break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
} else {
z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))))
break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
}
};
if (sign) {
-r
return -r;
} else {
r
return r;
}
}
@ -127,25 +127,25 @@ fn sin64(x_: f64) -> f64 {
const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
const w = z * z;
const r = {
const r = r: {
if (j == 1 or j == 2) {
1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))))
break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
} else {
z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))))
break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
}
};
if (sign) {
-r
return -r;
} else {
r
return r;
}
}
test "math.sin" {
assert(sin(f32(0.0)) == sin32(0.0));
assert(sin(f64(0.0)) == sin64(0.0));
assert(comptime {math.sin(f64(2))} == math.sin(f64(2)));
assert(comptime (math.sin(f64(2))) == math.sin(f64(2)));
}
test "math.sin32" {

View File

@ -11,11 +11,11 @@ const expo2 = @import("expo2.zig").expo2;
pub fn sinh(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(sinh32, x),
f64 => @inlineCall(sinh64, x),
else => @compileError("sinh not implemented for " ++ @typeName(T)),
}
};
}
// sinh(x) = (exp(x) - 1 / exp(x)) / 2
@ -49,7 +49,7 @@ fn sinh32(x: f32) -> f32 {
}
// |x| > log(FLT_MAX) or nan
2 * h * expo2(ax)
return 2 * h * expo2(ax);
}
fn sinh64(x: f64) -> f64 {
@ -83,7 +83,7 @@ fn sinh64(x: f64) -> f64 {
}
// |x| > log(DBL_MAX) or nan
2 * h * expo2(ax)
return 2 * h * expo2(ax);
}
test "math.sinh" {

View File

@ -14,7 +14,7 @@ pub fn sqrt(x: var) -> (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @
const T = @typeOf(x);
switch (@typeId(T)) {
TypeId.FloatLiteral => {
return T(sqrt64(x))
return T(sqrt64(x));
},
TypeId.Float => {
return switch (T) {
@ -64,7 +64,7 @@ fn sqrt32(x: f32) -> f32 {
// subnormal
var i: i32 = 0;
while (ix & 0x00800000 == 0) : (i += 1) {
ix <<= 1
ix <<= 1;
}
m -= i - 1;
}
@ -112,7 +112,7 @@ fn sqrt32(x: f32) -> f32 {
ix = (q >> 1) + 0x3f000000;
ix += m << 23;
@bitCast(f32, ix)
return @bitCast(f32, ix);
}
// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
@ -153,7 +153,7 @@ fn sqrt64(x: f64) -> f64 {
// subnormal
var i: u32 = 0;
while (ix0 & 0x00100000 == 0) : (i += 1) {
ix0 <<= 1
ix0 <<= 1;
}
m -= i32(i) - 1;
ix0 |= ix1 >> u5(32 - i);
@ -245,7 +245,7 @@ fn sqrt64(x: f64) -> f64 {
iix0 = iix0 +% (m << 20);
const uz = (u64(iix0) << 32) | ix1;
@bitCast(f64, uz)
return @bitCast(f64, uz);
}
test "math.sqrt" {

View File

@ -10,11 +10,11 @@ const assert = @import("../debug.zig").assert;
pub fn tan(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(tan32, x),
f64 => @inlineCall(tan64, x),
else => @compileError("tan not implemented for " ++ @typeName(T)),
}
};
}
const Tp0 = -1.30936939181383777646E4;
@ -62,11 +62,11 @@ fn tan32(x_: f32) -> f32 {
const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
const w = z * z;
var r = {
var r = r: {
if (w > 1e-14) {
z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4))
break :r z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4));
} else {
z
break :r z;
}
};
@ -77,7 +77,7 @@ fn tan32(x_: f32) -> f32 {
r = -r;
}
r
return r;
}
fn tan64(x_: f64) -> f64 {
@ -111,11 +111,11 @@ fn tan64(x_: f64) -> f64 {
const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
const w = z * z;
var r = {
var r = r: {
if (w > 1e-14) {
z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4))
break :r z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4));
} else {
z
break :r z;
}
};
@ -126,7 +126,7 @@ fn tan64(x_: f64) -> f64 {
r = -r;
}
r
return r;
}
test "math.tan" {

View File

@ -11,11 +11,11 @@ const expo2 = @import("expo2.zig").expo2;
pub fn tanh(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(tanh32, x),
f64 => @inlineCall(tanh64, x),
else => @compileError("tanh not implemented for " ++ @typeName(T)),
}
};
}
// tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
@ -59,9 +59,9 @@ fn tanh32(x: f32) -> f32 {
}
if (u >> 31 != 0) {
-t
return -t;
} else {
t
return t;
}
}
@ -104,9 +104,9 @@ fn tanh64(x: f64) -> f64 {
}
if (u >> 63 != 0) {
-t
return -t;
} else {
t
return t;
}
}

View File

@ -9,11 +9,11 @@ const assert = @import("../debug.zig").assert;
pub fn trunc(x: var) -> @typeOf(x) {
const T = @typeOf(x);
switch (T) {
return switch (T) {
f32 => @inlineCall(trunc32, x),
f64 => @inlineCall(trunc64, x),
else => @compileError("trunc not implemented for " ++ @typeName(T)),
}
};
}
fn trunc32(x: f32) -> f32 {
@ -30,10 +30,10 @@ fn trunc32(x: f32) -> f32 {
m = u32(@maxValue(u32)) >> u5(e);
if (u & m == 0) {
x
return x;
} else {
math.forceEval(x + 0x1p120);
@bitCast(f32, u & ~m)
return @bitCast(f32, u & ~m);
}
}
@ -51,10 +51,10 @@ fn trunc64(x: f64) -> f64 {
m = u64(@maxValue(u64)) >> u6(e);
if (u & m == 0) {
x
return x;
} else {
math.forceEval(x + 0x1p120);
@bitCast(f64, u & ~m)
return @bitCast(f64, u & ~m);
}
}

View File

@ -354,11 +354,11 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) -> bool {
/// split(" abc def ghi ", " ")
/// Will return slices for "abc", "def", "ghi", null, in that order.
pub fn split(buffer: []const u8, split_bytes: []const u8) -> SplitIterator {
SplitIterator {
return SplitIterator {
.index = 0,
.buffer = buffer,
.split_bytes = split_bytes,
}
};
}
test "mem.split" {
@ -552,7 +552,7 @@ test "std.mem.reverse" {
var arr = []i32{ 5, 3, 1, 2, 4 };
reverse(i32, arr[0..]);
assert(eql(i32, arr, []i32{ 4, 2, 1, 3, 5 }))
assert(eql(i32, arr, []i32{ 4, 2, 1, 3, 5 }));
}
/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
@ -567,5 +567,5 @@ test "std.mem.rotate" {
var arr = []i32{ 5, 3, 1, 2, 4 };
rotate(i32, arr[0..], 2);
assert(eql(i32, arr, []i32{ 1, 2, 4, 5, 3 }))
assert(eql(i32, arr, []i32{ 1, 2, 4, 5, 3 }));
}

View File

@ -72,7 +72,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
// if (family != AF_INET)
// buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } };
//
unreachable // TODO
unreachable; // TODO
}
// TODO
@ -84,7 +84,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
// else => {},
//};
unreachable // TODO
unreachable; // TODO
}
pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
@ -96,23 +96,23 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
}
const socket_fd = i32(socket_ret);
const connect_ret = if (addr.family == linux.AF_INET) {
const connect_ret = if (addr.family == linux.AF_INET) x: {
var os_addr: linux.sockaddr_in = undefined;
os_addr.family = addr.family;
os_addr.port = endian.swapIfLe(u16, port);
@memcpy((&u8)(&os_addr.addr), &addr.addr[0], 4);
@memset(&os_addr.zero[0], 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) {
break :x linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeOf(linux.sockaddr_in));
} else if (addr.family == linux.AF_INET6) x: {
var os_addr: linux.sockaddr_in6 = undefined;
os_addr.family = addr.family;
os_addr.port = endian.swapIfLe(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))
break :x linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeOf(linux.sockaddr_in6));
} else {
unreachable
unreachable;
};
const connect_err = linux.getErrno(connect_ret);
if (connect_err > 0) {
@ -165,13 +165,13 @@ pub fn parseIpLiteral(buf: []const u8) -> %Address {
fn hexDigit(c: u8) -> u8 {
// TODO use switch with range
if ('0' <= c and c <= '9') {
c - '0'
return c - '0';
} else if ('A' <= c and c <= 'Z') {
c - 'A' + 10
return c - 'A' + 10;
} else if ('a' <= c and c <= 'z') {
c - 'a' + 10
return c - 'a' + 10;
} else {
@maxValue(u8)
return @maxValue(u8);
}
}

View File

@ -115,7 +115,7 @@ pub const ChildProcess = struct {
return self.spawnWindows();
} else {
return self.spawnPosix();
};
}
}
pub fn spawnAndWait(self: &ChildProcess) -> %Term {
@ -249,12 +249,12 @@ pub const ChildProcess = struct {
fn waitUnwrappedWindows(self: &ChildProcess) -> %void {
const result = os.windowsWaitSingle(self.handle, windows.INFINITE);
self.term = (%Term)({
self.term = (%Term)(x: {
var exit_code: windows.DWORD = undefined;
if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {
Term { .Unknown = 0 }
break :x Term { .Unknown = 0 };
} else {
Term { .Exited = @bitCast(i32, exit_code)}
break :x Term { .Exited = @bitCast(i32, exit_code)};
}
});
@ -300,7 +300,7 @@ pub const ChildProcess = struct {
defer {
os.close(self.err_pipe[0]);
os.close(self.err_pipe[1]);
};
}
// Write @maxValue(ErrInt) to the write end of the err_pipe. This is after
// waitpid, so this write is guaranteed to be after the child
@ -319,15 +319,15 @@ pub const ChildProcess = struct {
}
fn statusToTerm(status: i32) -> Term {
return if (posix.WIFEXITED(status)) {
return if (posix.WIFEXITED(status))
Term { .Exited = posix.WEXITSTATUS(status) }
} else if (posix.WIFSIGNALED(status)) {
else if (posix.WIFSIGNALED(status))
Term { .Signal = posix.WTERMSIG(status) }
} else if (posix.WIFSTOPPED(status)) {
else if (posix.WIFSTOPPED(status))
Term { .Stopped = posix.WSTOPSIG(status) }
} else {
else
Term { .Unknown = status }
};
;
}
fn spawnPosix(self: &ChildProcess) -> %void {
@ -344,22 +344,22 @@ pub const ChildProcess = struct {
%defer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); };
const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
const dev_null_fd = if (any_ignore) {
const dev_null_fd = if (any_ignore)
%return os.posixOpen("/dev/null", posix.O_RDWR, 0, null)
} else {
else
undefined
};
defer { if (any_ignore) os.close(dev_null_fd); };
;
defer { if (any_ignore) os.close(dev_null_fd); }
var env_map_owned: BufMap = undefined;
var we_own_env_map: bool = undefined;
const env_map = if (self.env_map) |env_map| {
const env_map = if (self.env_map) |env_map| x: {
we_own_env_map = false;
env_map
} else {
break :x env_map;
} else x: {
we_own_env_map = true;
env_map_owned = %return os.getEnvMap(self.allocator);
&env_map_owned
break :x &env_map_owned;
};
defer { if (we_own_env_map) env_map_owned.deinit(); }
@ -450,13 +450,13 @@ pub const ChildProcess = struct {
self.stdout_behavior == StdIo.Ignore or
self.stderr_behavior == StdIo.Ignore);
const nul_handle = if (any_ignore) {
const nul_handle = if (any_ignore)
%return os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ,
windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null)
} else {
else
undefined
};
defer { if (any_ignore) os.close(nul_handle); };
;
defer { if (any_ignore) os.close(nul_handle); }
if (any_ignore) {
%return windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0);
}
@ -542,30 +542,30 @@ pub const ChildProcess = struct {
};
var piProcInfo: windows.PROCESS_INFORMATION = undefined;
const cwd_slice = if (self.cwd) |cwd| {
const cwd_slice = if (self.cwd) |cwd|
%return cstr.addNullByte(self.allocator, cwd)
} else {
else
null
};
;
defer if (cwd_slice) |cwd| self.allocator.free(cwd);
const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null;
const maybe_envp_buf = if (self.env_map) |env_map| {
const maybe_envp_buf = if (self.env_map) |env_map|
%return os.createWindowsEnvBlock(self.allocator, env_map)
} else {
else
null
};
;
defer if (maybe_envp_buf) |envp_buf| self.allocator.free(envp_buf);
const envp_ptr = if (maybe_envp_buf) |envp_buf| envp_buf.ptr else null;
// the cwd set in ChildProcess is in effect when choosing the executable path
// to match posix semantics
const app_name = if (self.cwd) |cwd| {
const app_name = if (self.cwd) |cwd| x: {
const resolved = %return os.path.resolve(self.allocator, cwd, self.argv[0]);
defer self.allocator.free(resolved);
%return cstr.addNullByte(self.allocator, resolved)
} else {
%return cstr.addNullByte(self.allocator, self.argv[0])
break :x %return cstr.addNullByte(self.allocator, resolved);
} else x: {
break :x %return cstr.addNullByte(self.allocator, self.argv[0]);
};
defer self.allocator.free(app_name);
@ -741,7 +741,7 @@ fn makePipe() -> %[2]i32 {
return switch (err) {
posix.EMFILE, posix.ENFILE => error.SystemResources,
else => os.unexpectedErrorPosix(err),
}
};
}
return fds;
}
@ -800,10 +800,10 @@ fn handleTerm(pid: i32, status: i32) {
}
}
const sigchld_set = {
const sigchld_set = x: {
var signal_set = posix.empty_sigset;
posix.sigaddset(&signal_set, posix.SIGCHLD);
signal_set
break :x signal_set;
};
fn block_SIGCHLD() {

View File

@ -97,63 +97,63 @@ pub const SIGINFO = 29; /// information request
pub const SIGUSR1 = 30; /// user defined signal 1
pub const SIGUSR2 = 31; /// user defined signal 2
fn wstatus(x: i32) -> i32 { x & 0o177 }
fn wstatus(x: i32) -> i32 { return x & 0o177; }
const wstopped = 0o177;
pub fn WEXITSTATUS(x: i32) -> i32 { x >> 8 }
pub fn WTERMSIG(x: i32) -> i32 { wstatus(x) }
pub fn WSTOPSIG(x: i32) -> i32 { x >> 8 }
pub fn WIFEXITED(x: i32) -> bool { wstatus(x) == 0 }
pub fn WIFSTOPPED(x: i32) -> bool { wstatus(x) == wstopped and WSTOPSIG(x) != 0x13 }
pub fn WIFSIGNALED(x: i32) -> bool { wstatus(x) != wstopped and wstatus(x) != 0 }
pub fn WEXITSTATUS(x: i32) -> i32 { return x >> 8; }
pub fn WTERMSIG(x: i32) -> i32 { return wstatus(x); }
pub fn WSTOPSIG(x: i32) -> i32 { return x >> 8; }
pub fn WIFEXITED(x: i32) -> bool { return wstatus(x) == 0; }
pub fn WIFSTOPPED(x: i32) -> bool { return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13; }
pub fn WIFSIGNALED(x: i32) -> bool { return wstatus(x) != wstopped and wstatus(x) != 0; }
/// Get the errno from a syscall return value, or 0 for no error.
pub fn getErrno(r: usize) -> usize {
const signed_r = @bitCast(isize, r);
if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
}
pub fn close(fd: i32) -> usize {
errnoWrap(c.close(fd))
return errnoWrap(c.close(fd));
}
pub fn abort() -> noreturn {
c.abort()
return c.abort();
}
pub fn exit(code: i32) -> noreturn {
c.exit(code)
return c.exit(code);
}
pub fn isatty(fd: i32) -> bool {
c.isatty(fd) != 0
return c.isatty(fd) != 0;
}
pub fn fstat(fd: i32, buf: &c.Stat) -> usize {
errnoWrap(c.@"fstat$INODE64"(fd, buf))
return errnoWrap(c.@"fstat$INODE64"(fd, buf));
}
pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize {
errnoWrap(c.lseek(fd, offset, whence))
return errnoWrap(c.lseek(fd, offset, whence));
}
pub fn open(path: &const u8, flags: u32, mode: usize) -> usize {
errnoWrap(c.open(path, @bitCast(c_int, flags), mode))
return errnoWrap(c.open(path, @bitCast(c_int, flags), mode));
}
pub fn raise(sig: i32) -> usize {
errnoWrap(c.raise(sig))
return errnoWrap(c.raise(sig));
}
pub fn read(fd: i32, buf: &u8, nbyte: usize) -> usize {
errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte))
return errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte));
}
pub fn stat(noalias path: &const u8, noalias buf: &stat) -> usize {
errnoWrap(c.stat(path, buf))
return errnoWrap(c.stat(path, buf));
}
pub fn write(fd: i32, buf: &const u8, nbyte: usize) -> usize {
errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte))
return errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte));
}
pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
@ -166,79 +166,79 @@ pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
}
pub fn munmap(address: &u8, length: usize) -> usize {
errnoWrap(c.munmap(@ptrCast(&c_void, address), length))
return errnoWrap(c.munmap(@ptrCast(&c_void, address), length));
}
pub fn unlink(path: &const u8) -> usize {
errnoWrap(c.unlink(path))
return errnoWrap(c.unlink(path));
}
pub fn getcwd(buf: &u8, size: usize) -> usize {
if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0
return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0;
}
pub fn waitpid(pid: i32, status: &i32, options: u32) -> usize {
comptime assert(i32.bit_count == c_int.bit_count);
errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)))
return errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)));
}
pub fn fork() -> usize {
errnoWrap(c.fork())
return errnoWrap(c.fork());
}
pub fn pipe(fds: &[2]i32) -> usize {
comptime assert(i32.bit_count == c_int.bit_count);
errnoWrap(c.pipe(@ptrCast(&c_int, fds)))
return errnoWrap(c.pipe(@ptrCast(&c_int, fds)));
}
pub fn mkdir(path: &const u8, mode: u32) -> usize {
errnoWrap(c.mkdir(path, mode))
return errnoWrap(c.mkdir(path, mode));
}
pub fn symlink(existing: &const u8, new: &const u8) -> usize {
errnoWrap(c.symlink(existing, new))
return errnoWrap(c.symlink(existing, new));
}
pub fn rename(old: &const u8, new: &const u8) -> usize {
errnoWrap(c.rename(old, new))
return errnoWrap(c.rename(old, new));
}
pub fn chdir(path: &const u8) -> usize {
errnoWrap(c.chdir(path))
return errnoWrap(c.chdir(path));
}
pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8)
-> usize
{
errnoWrap(c.execve(path, argv, envp))
return errnoWrap(c.execve(path, argv, envp));
}
pub fn dup2(old: i32, new: i32) -> usize {
errnoWrap(c.dup2(old, new))
return errnoWrap(c.dup2(old, new));
}
pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize {
errnoWrap(c.readlink(path, buf_ptr, buf_len))
return errnoWrap(c.readlink(path, buf_ptr, buf_len));
}
pub fn nanosleep(req: &const timespec, rem: ?&timespec) -> usize {
errnoWrap(c.nanosleep(req, rem))
return errnoWrap(c.nanosleep(req, rem));
}
pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) -> usize {
if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0
return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0;
}
pub fn setreuid(ruid: u32, euid: u32) -> usize {
errnoWrap(c.setreuid(ruid, euid))
return errnoWrap(c.setreuid(ruid, euid));
}
pub fn setregid(rgid: u32, egid: u32) -> usize {
errnoWrap(c.setregid(rgid, egid))
return errnoWrap(c.setregid(rgid, egid));
}
pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) -> usize {
errnoWrap(c.sigprocmask(@bitCast(c_int, flags), set, oldset))
return errnoWrap(c.sigprocmask(@bitCast(c_int, flags), set, oldset));
}
pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> usize {
@ -285,9 +285,5 @@ pub fn sigaddset(set: &sigset_t, signo: u5) {
/// that the kernel represents it to libc. Errno was a mistake, let's make
/// it go away forever.
fn errnoWrap(value: isize) -> usize {
@bitCast(usize, if (value == -1) {
-isize(*c._errno())
} else {
value
})
return @bitCast(usize, if (value == -1) -isize(*c._errno()) else value);
}

View File

@ -84,7 +84,7 @@ pub fn getRandomBytes(buf: []u8) -> %void {
posix.EFAULT => unreachable,
posix.EINTR => continue,
else => unexpectedErrorPosix(err),
}
};
}
return;
},
@ -151,18 +151,17 @@ pub coldcc fn exit(status: i32) -> noreturn {
}
switch (builtin.os) {
Os.linux, Os.darwin, Os.macosx, Os.ios => {
posix.exit(status)
posix.exit(status);
},
Os.windows => {
// Map a possibly negative status code to a non-negative status for the systems default
// integer width.
const p_status = if (@sizeOf(c_uint) < @sizeOf(u32)) {
const p_status = if (@sizeOf(c_uint) < @sizeOf(u32))
@truncate(c_uint, @bitCast(u32, status))
} else {
c_uint(@bitCast(u32, status))
};
else
c_uint(@bitCast(u32, status));
windows.ExitProcess(p_status)
windows.ExitProcess(p_status);
},
else => @compileError("Unsupported OS"),
}
@ -289,7 +288,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
posix.EPERM => error.AccessDenied,
posix.EEXIST => error.PathAlreadyExists,
else => unexpectedErrorPosix(err),
}
};
}
return i32(result);
}
@ -680,7 +679,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void
windows.ERROR.ACCESS_DENIED => error.AccessDenied,
windows.ERROR.FILENAME_EXCED_RANGE, windows.ERROR.INVALID_PARAMETER => error.NameTooLong,
else => unexpectedErrorWindows(err),
}
};
}
}
@ -1006,7 +1005,7 @@ pub const Dir = struct {
continue;
},
else => return unexpectedErrorPosix(err),
};
}
}
if (result == 0)
return null;

View File

@ -367,14 +367,14 @@ pub const TFD_CLOEXEC = O_CLOEXEC;
pub const TFD_TIMER_ABSTIME = 1;
pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
fn unsigned(s: i32) -> u32 { @bitCast(u32, s) }
fn signed(s: u32) -> i32 { @bitCast(i32, s) }
pub fn WEXITSTATUS(s: i32) -> i32 { signed((unsigned(s) & 0xff00) >> 8) }
pub fn WTERMSIG(s: i32) -> i32 { signed(unsigned(s) & 0x7f) }
pub fn WSTOPSIG(s: i32) -> i32 { WEXITSTATUS(s) }
pub fn WIFEXITED(s: i32) -> bool { WTERMSIG(s) == 0 }
pub fn WIFSTOPPED(s: i32) -> bool { (u16)(((unsigned(s)&0xffff)*%0x10001)>>8) > 0x7f00 }
pub fn WIFSIGNALED(s: i32) -> bool { (unsigned(s)&0xffff)-%1 < 0xff }
fn unsigned(s: i32) -> u32 { return @bitCast(u32, s); }
fn signed(s: u32) -> i32 { return @bitCast(i32, s); }
pub fn WEXITSTATUS(s: i32) -> i32 { return signed((unsigned(s) & 0xff00) >> 8); }
pub fn WTERMSIG(s: i32) -> i32 { return signed(unsigned(s) & 0x7f); }
pub fn WSTOPSIG(s: i32) -> i32 { return WEXITSTATUS(s); }
pub fn WIFEXITED(s: i32) -> bool { return WTERMSIG(s) == 0; }
pub fn WIFSTOPPED(s: i32) -> bool { return (u16)(((unsigned(s)&0xffff)*%0x10001)>>8) > 0x7f00; }
pub fn WIFSIGNALED(s: i32) -> bool { return (unsigned(s)&0xffff)-%1 < 0xff; }
pub const winsize = extern struct {
@ -387,31 +387,31 @@ pub const winsize = extern struct {
/// Get the errno from a syscall return value, or 0 for no error.
pub fn getErrno(r: usize) -> usize {
const signed_r = @bitCast(isize, r);
if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
}
pub fn dup2(old: i32, new: i32) -> usize {
arch.syscall2(arch.SYS_dup2, usize(old), usize(new))
return arch.syscall2(arch.SYS_dup2, usize(old), usize(new));
}
pub fn chdir(path: &const u8) -> usize {
arch.syscall1(arch.SYS_chdir, @ptrToInt(path))
return arch.syscall1(arch.SYS_chdir, @ptrToInt(path));
}
pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize {
arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp))
return arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));
}
pub fn fork() -> usize {
arch.syscall0(arch.SYS_fork)
return arch.syscall0(arch.SYS_fork);
}
pub fn getcwd(buf: &u8, size: usize) -> usize {
arch.syscall2(arch.SYS_getcwd, @ptrToInt(buf), size)
return arch.syscall2(arch.SYS_getcwd, @ptrToInt(buf), size);
}
pub fn getdents(fd: i32, dirp: &u8, count: usize) -> usize {
arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count)
return arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count);
}
pub fn isatty(fd: i32) -> bool {
@ -420,123 +420,123 @@ pub fn isatty(fd: i32) -> bool {
}
pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize {
arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len)
return arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
}
pub fn mkdir(path: &const u8, mode: u32) -> usize {
arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode)
return arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode);
}
pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize)
-> usize
{
arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),
@bitCast(usize, offset))
return arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),
@bitCast(usize, offset));
}
pub fn munmap(address: &u8, length: usize) -> usize {
arch.syscall2(arch.SYS_munmap, @ptrToInt(address), length)
return arch.syscall2(arch.SYS_munmap, @ptrToInt(address), length);
}
pub fn read(fd: i32, buf: &u8, count: usize) -> usize {
arch.syscall3(arch.SYS_read, usize(fd), @ptrToInt(buf), count)
return arch.syscall3(arch.SYS_read, usize(fd), @ptrToInt(buf), count);
}
pub fn rmdir(path: &const u8) -> usize {
arch.syscall1(arch.SYS_rmdir, @ptrToInt(path))
return arch.syscall1(arch.SYS_rmdir, @ptrToInt(path));
}
pub fn symlink(existing: &const u8, new: &const u8) -> usize {
arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new))
return arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
}
pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) -> usize {
arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset)
return arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset);
}
pub fn pipe(fd: &[2]i32) -> usize {
pipe2(fd, 0)
return pipe2(fd, 0);
}
pub fn pipe2(fd: &[2]i32, flags: usize) -> usize {
arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags)
return arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags);
}
pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {
arch.syscall3(arch.SYS_write, usize(fd), @ptrToInt(buf), count)
return arch.syscall3(arch.SYS_write, usize(fd), @ptrToInt(buf), count);
}
pub fn pwrite(fd: i32, buf: &const u8, count: usize, offset: usize) -> usize {
arch.syscall4(arch.SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset)
return arch.syscall4(arch.SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);
}
pub fn rename(old: &const u8, new: &const u8) -> usize {
arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new))
return arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new));
}
pub fn open(path: &const u8, flags: u32, perm: usize) -> usize {
arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm)
return arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm);
}
pub fn create(path: &const u8, perm: usize) -> usize {
arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm)
return arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm);
}
pub fn openat(dirfd: i32, path: &const u8, flags: usize, mode: usize) -> usize {
arch.syscall4(arch.SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode)
return arch.syscall4(arch.SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);
}
pub fn close(fd: i32) -> usize {
arch.syscall1(arch.SYS_close, usize(fd))
return arch.syscall1(arch.SYS_close, usize(fd));
}
pub fn lseek(fd: i32, offset: isize, ref_pos: usize) -> usize {
arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos)
return arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos);
}
pub fn exit(status: i32) -> noreturn {
_ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status)));
unreachable
unreachable;
}
pub fn getrandom(buf: &u8, count: usize, flags: u32) -> usize {
arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, usize(flags))
return arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, usize(flags));
}
pub fn kill(pid: i32, sig: i32) -> usize {
arch.syscall2(arch.SYS_kill, @bitCast(usize, isize(pid)), usize(sig))
return arch.syscall2(arch.SYS_kill, @bitCast(usize, isize(pid)), usize(sig));
}
pub fn unlink(path: &const u8) -> usize {
arch.syscall1(arch.SYS_unlink, @ptrToInt(path))
return arch.syscall1(arch.SYS_unlink, @ptrToInt(path));
}
pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize {
arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0)
return arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
}
pub fn nanosleep(req: &const timespec, rem: ?&timespec) -> usize {
arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem))
return arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem));
}
pub fn setuid(uid: u32) -> usize {
arch.syscall1(arch.SYS_setuid, uid)
return arch.syscall1(arch.SYS_setuid, uid);
}
pub fn setgid(gid: u32) -> usize {
arch.syscall1(arch.SYS_setgid, gid)
return arch.syscall1(arch.SYS_setgid, gid);
}
pub fn setreuid(ruid: u32, euid: u32) -> usize {
arch.syscall2(arch.SYS_setreuid, ruid, euid)
return arch.syscall2(arch.SYS_setreuid, ruid, euid);
}
pub fn setregid(rgid: u32, egid: u32) -> usize {
arch.syscall2(arch.SYS_setregid, rgid, egid)
return arch.syscall2(arch.SYS_setregid, rgid, egid);
}
pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) -> usize {
arch.syscall4(arch.SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8)
return arch.syscall4(arch.SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8);
}
pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> usize {
@ -652,69 +652,69 @@ pub const iovec = extern struct {
};
pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {
arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len))
return arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len));
}
pub fn getpeername(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {
arch.syscall3(arch.SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len))
return arch.syscall3(arch.SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len));
}
pub fn socket(domain: i32, socket_type: i32, protocol: i32) -> usize {
arch.syscall3(arch.SYS_socket, usize(domain), usize(socket_type), usize(protocol))
return arch.syscall3(arch.SYS_socket, usize(domain), usize(socket_type), usize(protocol));
}
pub fn setsockopt(fd: i32, level: i32, optname: i32, optval: &const u8, optlen: socklen_t) -> usize {
arch.syscall5(arch.SYS_setsockopt, usize(fd), usize(level), usize(optname), usize(optval), @ptrToInt(optlen))
return arch.syscall5(arch.SYS_setsockopt, usize(fd), usize(level), usize(optname), usize(optval), @ptrToInt(optlen));
}
pub fn getsockopt(fd: i32, level: i32, optname: i32, noalias optval: &u8, noalias optlen: &socklen_t) -> usize {
arch.syscall5(arch.SYS_getsockopt, usize(fd), usize(level), usize(optname), @ptrToInt(optval), @ptrToInt(optlen))
return arch.syscall5(arch.SYS_getsockopt, usize(fd), usize(level), usize(optname), @ptrToInt(optval), @ptrToInt(optlen));
}
pub fn sendmsg(fd: i32, msg: &const arch.msghdr, flags: u32) -> usize {
arch.syscall3(arch.SYS_sendmsg, usize(fd), @ptrToInt(msg), flags)
return arch.syscall3(arch.SYS_sendmsg, usize(fd), @ptrToInt(msg), flags);
}
pub fn connect(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize {
arch.syscall3(arch.SYS_connect, usize(fd), @ptrToInt(addr), usize(len))
return arch.syscall3(arch.SYS_connect, usize(fd), @ptrToInt(addr), usize(len));
}
pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: u32) -> usize {
arch.syscall3(arch.SYS_recvmsg, usize(fd), @ptrToInt(msg), flags)
return arch.syscall3(arch.SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);
}
pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32,
noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) -> usize
{
arch.syscall6(arch.SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen))
return arch.syscall6(arch.SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
}
pub fn shutdown(fd: i32, how: i32) -> usize {
arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how))
return arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how));
}
pub fn bind(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize {
arch.syscall3(arch.SYS_bind, usize(fd), @ptrToInt(addr), usize(len))
return arch.syscall3(arch.SYS_bind, usize(fd), @ptrToInt(addr), usize(len));
}
pub fn listen(fd: i32, backlog: i32) -> usize {
arch.syscall2(arch.SYS_listen, usize(fd), usize(backlog))
return arch.syscall2(arch.SYS_listen, usize(fd), usize(backlog));
}
pub fn sendto(fd: i32, buf: &const u8, len: usize, flags: u32, addr: ?&const sockaddr, alen: socklen_t) -> usize {
arch.syscall6(arch.SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen))
return arch.syscall6(arch.SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));
}
pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) -> usize {
arch.syscall4(arch.SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(&fd[0]))
return arch.syscall4(arch.SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(&fd[0]));
}
pub fn accept(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {
accept4(fd, addr, len, 0)
return accept4(fd, addr, len, 0);
}
pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags: u32) -> usize {
arch.syscall4(arch.SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags)
return arch.syscall4(arch.SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags);
}
// error NameTooLong;
@ -749,7 +749,7 @@ pub const Stat = arch.Stat;
pub const timespec = arch.timespec;
pub fn fstat(fd: i32, stat_buf: &Stat) -> usize {
arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf))
return arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf));
}
pub const epoll_data = u64;
@ -760,19 +760,19 @@ pub const epoll_event = extern struct {
};
pub fn epoll_create() -> usize {
arch.syscall1(arch.SYS_epoll_create, usize(1))
return arch.syscall1(arch.SYS_epoll_create, usize(1));
}
pub fn epoll_ctl(epoll_fd: i32, op: i32, fd: i32, ev: &epoll_event) -> usize {
arch.syscall4(arch.SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev))
return arch.syscall4(arch.SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));
}
pub fn epoll_wait(epoll_fd: i32, events: &epoll_event, maxevents: i32, timeout: i32) -> usize {
arch.syscall4(arch.SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout))
return arch.syscall4(arch.SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));
}
pub fn timerfd_create(clockid: i32, flags: u32) -> usize {
arch.syscall2(arch.SYS_timerfd_create, usize(clockid), usize(flags))
return arch.syscall2(arch.SYS_timerfd_create, usize(clockid), usize(flags));
}
pub const itimerspec = extern struct {
@ -781,11 +781,11 @@ pub const itimerspec = extern struct {
};
pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) -> usize {
arch.syscall2(arch.SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value))
return arch.syscall2(arch.SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value));
}
pub fn timerfd_settime(fd: i32, flags: u32, new_value: &const itimerspec, old_value: ?&itimerspec) -> usize {
arch.syscall4(arch.SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value))
return arch.syscall4(arch.SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value));
}
test "import linux_test" {

View File

@ -371,52 +371,52 @@ pub const F_GETOWN_EX = 16;
pub const F_GETOWNER_UIDS = 17;
pub fn syscall0(number: usize) -> usize {
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number)
: "rcx", "r11")
: "rcx", "r11");
}
pub fn syscall1(number: usize, arg1: usize) -> usize {
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1)
: "rcx", "r11")
: "rcx", "r11");
}
pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1),
[arg2] "{rsi}" (arg2)
: "rcx", "r11")
: "rcx", "r11");
}
pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1),
[arg2] "{rsi}" (arg2),
[arg3] "{rdx}" (arg3)
: "rcx", "r11")
: "rcx", "r11");
}
pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1),
[arg2] "{rsi}" (arg2),
[arg3] "{rdx}" (arg3),
[arg4] "{r10}" (arg4)
: "rcx", "r11")
: "rcx", "r11");
}
pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> usize {
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1),
@ -424,13 +424,13 @@ pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
[arg3] "{rdx}" (arg3),
[arg4] "{r10}" (arg4),
[arg5] "{r8}" (arg5)
: "rcx", "r11")
: "rcx", "r11");
}
pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
arg5: usize, arg6: usize) -> usize
{
asm volatile ("syscall"
return asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1),
@ -439,14 +439,14 @@ pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
[arg4] "{r10}" (arg4),
[arg5] "{r8}" (arg5),
[arg6] "{r9}" (arg6)
: "rcx", "r11")
: "rcx", "r11");
}
pub nakedcc fn restore_rt() {
asm volatile ("syscall"
return asm volatile ("syscall"
:
: [number] "{rax}" (usize(SYS_rt_sigreturn))
: "rcx", "r11")
: "rcx", "r11");
}

View File

@ -749,21 +749,19 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
const resolved_to = %return resolveWindows(allocator, [][]const u8{to});
defer if (clean_up_resolved_to) allocator.free(resolved_to);
const result_is_to = if (drive(resolved_to)) |to_drive| {
if (drive(resolved_from)) |from_drive| {
const result_is_to = if (drive(resolved_to)) |to_drive|
if (drive(resolved_from)) |from_drive|
asciiUpper(from_drive[0]) != asciiUpper(to_drive[0])
} else {
else
true
}
} else if (networkShare(resolved_to)) |to_ns| {
if (networkShare(resolved_from)) |from_ns| {
else if (networkShare(resolved_to)) |to_ns|
if (networkShare(resolved_from)) |from_ns|
!networkShareServersEql(to_ns, from_ns)
} else {
else
true
}
} else {
unreachable
};
else
unreachable;
if (result_is_to) {
clean_up_resolved_to = false;
return resolved_to;
@ -964,14 +962,16 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
// windows returns \\?\ prepended to the path
// we strip it because nobody wants \\?\ prepended to their path
const final_len = if (result > 4 and mem.startsWith(u8, buf, "\\\\?\\")) {
const final_len = x: {
if (result > 4 and mem.startsWith(u8, buf, "\\\\?\\")) {
var i: usize = 4;
while (i < result) : (i += 1) {
buf[i - 4] = buf[i];
}
result - 4
break :x result - 4;
} else {
result
break :x result;
}
};
return allocator.shrink(u8, buf, final_len);

View File

@ -122,7 +122,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m
/// Caller must free result.
pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) -> %[]u8 {
// count bytes needed
const bytes_needed = {
const bytes_needed = x: {
var bytes_needed: usize = 1; // 1 for the final null byte
var it = env_map.iterator();
while (it.next()) |pair| {
@ -130,7 +130,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
// +1 for null byte
bytes_needed += pair.key.len + pair.value.len + 2;
}
bytes_needed
break :x bytes_needed;
};
const result = %return allocator.alloc(u8, bytes_needed);
%defer allocator.free(result);

View File

@ -28,9 +28,9 @@ pub const Rand = struct {
/// Initialize random state with the given seed.
pub fn init(seed: usize) -> Rand {
Rand {
return Rand {
.rng = Rng.init(seed),
}
};
}
/// Get an integer or boolean with random bits.
@ -78,13 +78,13 @@ pub const Rand = struct {
const end_uint = uint(end);
const total_range = math.absCast(start) + end_uint;
const value = r.range(uint, 0, total_range);
const result = if (value < end_uint) {
T(value)
} else if (value == end_uint) {
start
} else {
const result = if (value < end_uint) x: {
break :x T(value);
} else if (value == end_uint) x: {
break :x start;
} else x: {
// Can't overflow because the range is over signed ints
%%math.negateCast(value - end_uint)
break :x %%math.negateCast(value - end_uint);
};
return result;
} else {
@ -114,13 +114,13 @@ pub const Rand = struct {
// const rand_bits = r.rng.scalar(int) & mask;
// return @float_compose(T, false, 0, rand_bits) - 1.0
const int_type = @IntType(false, @sizeOf(T) * 8);
const precision = if (T == f32) {
const precision = if (T == f32)
16777216
} else if (T == f64) {
else if (T == f64)
9007199254740992
} else {
else
@compileError("unknown floating point type")
};
;
return T(r.range(int_type, 0, precision)) / T(precision);
}
};
@ -133,7 +133,7 @@ fn MersenneTwister(
comptime t: math.Log2Int(int), comptime c: int,
comptime l: math.Log2Int(int), comptime f: int) -> type
{
struct {
return struct {
const Self = this;
array: [n]int,
@ -189,7 +189,7 @@ fn MersenneTwister(
return x;
}
}
};
}
test "rand float 32" {

View File

@ -355,7 +355,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
// these values will be pulled out to the start of A
last = A.start;
count = 1;
while (count < find) : ({last = index; count += 1}) {
while (count < find) : ({last = index; count += 1;}) {
index = findLastForward(T, items, items[last], Range.init(last + 1, A.end), lessThan, find - count);
if (index == A.end) break;
}
@ -410,7 +410,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
// these values will be pulled out to the end of B
last = B.end - 1;
count = 1;
while (count < find) : ({last = index - 1; count += 1}) {
while (count < find) : ({last = index - 1; count += 1;}) {
index = findFirstBackward(T, items, items[last], Range.init(B.start, last), lessThan, find - count);
if (index == B.start) break;
}
@ -547,7 +547,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
// swap the first value of each A block with the value in buffer1
var indexA = buffer1.start;
index = firstA.end;
while (index < blockA.end) : ({indexA += 1; index += block_size}) {
while (index < blockA.end) : ({indexA += 1; index += block_size;}) {
mem.swap(T, &items[indexA], &items[index]);
}
@ -1093,7 +1093,7 @@ test "another sort case" {
var arr = []i32{ 5, 3, 1, 2, 4 };
sort(i32, arr[0..], i32asc);
assert(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }))
assert(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }));
}
test "sort fuzz testing" {

View File

@ -45,21 +45,17 @@ pub fn main() -> %void {
var stderr_file = io.getStdErr();
var stderr_file_stream: io.FileOutStream = undefined;
var stderr_stream: %&io.OutStream = if (stderr_file) |*f| {
var stderr_stream: %&io.OutStream = if (stderr_file) |*f| x: {
stderr_file_stream = io.FileOutStream.init(f);
&stderr_file_stream.stream
} else |err| {
err
};
break :x &stderr_file_stream.stream;
} else |err| err;
var stdout_file = io.getStdOut();
var stdout_file_stream: io.FileOutStream = undefined;
var stdout_stream: %&io.OutStream = if (stdout_file) |*f| {
var stdout_stream: %&io.OutStream = if (stdout_file) |*f| x: {
stdout_file_stream = io.FileOutStream.init(f);
&stdout_file_stream.stream
} else |err| {
err
};
break :x &stdout_file_stream.stream;
} else |err| err;
while (arg_it.next(allocator)) |err_or_arg| {
const arg = %return unwrapArg(err_or_arg);

View File

@ -46,15 +46,15 @@ extern fn __stack_chk_fail() -> noreturn {
const math = @import("../math/index.zig");
export fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) }
export fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) }
export fn fmodf(x: f32, y: f32) -> f32 { return generic_fmod(f32, x, y); }
export fn fmod(x: f64, y: f64) -> f64 { return generic_fmod(f64, x, y); }
// TODO add intrinsics for these (and probably the double version too)
// and have the math stuff use the intrinsic. same as @mod and @rem
export fn floorf(x: f32) -> f32 { math.floor(x) }
export fn ceilf(x: f32) -> f32 { math.ceil(x) }
export fn floor(x: f64) -> f64 { math.floor(x) }
export fn ceil(x: f64) -> f64 { math.ceil(x) }
export fn floorf(x: f32) -> f32 { return math.floor(x); }
export fn ceilf(x: f32) -> f32 { return math.ceil(x); }
export fn floor(x: f64) -> f64 { return math.floor(x); }
export fn ceil(x: f64) -> f64 { return math.ceil(x); }
fn generic_fmod(comptime T: type, x: T, y: T) -> T {
@setDebugSafety(this, false);
@ -84,7 +84,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) -> T {
// normalize x and y
if (ex == 0) {
i = ux << exp_bits;
while (i >> bits_minus_1 == 0) : ({ex -= 1; i <<= 1}) {}
while (i >> bits_minus_1 == 0) : (b: {ex -= 1; break :b i <<= 1;}) {}
ux <<= log2uint(@bitCast(u32, -ex + 1));
} else {
ux &= @maxValue(uint) >> exp_bits;
@ -92,7 +92,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) -> T {
}
if (ey == 0) {
i = uy << exp_bits;
while (i >> bits_minus_1 == 0) : ({ey -= 1; i <<= 1}) {}
while (i >> bits_minus_1 == 0) : (b: {ey -= 1; break :b i <<= 1;}) {}
uy <<= log2uint(@bitCast(u32, -ey + 1));
} else {
uy &= @maxValue(uint) >> exp_bits;
@ -115,7 +115,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) -> T {
return 0 * x;
ux = i;
}
while (ux >> digits == 0) : ({ux <<= 1; ex -= 1}) {}
while (ux >> digits == 0) : (b: {ux <<= 1; break :b ex -= 1;}) {}
// scale result up
if (ex > 0) {

View File

@ -38,27 +38,25 @@ pub extern fn __letf2(a: f128, b: f128) -> c_int {
// If at least one of a and b is positive, we get the same result comparing
// a and b as signed integers as we would with a floating-point compare.
return if ((aInt & bInt) >= 0) {
if (aInt < bInt) {
return if ((aInt & bInt) >= 0)
if (aInt < bInt)
LE_LESS
} else if (aInt == bInt) {
else if (aInt == bInt)
LE_EQUAL
} else {
else
LE_GREATER
}
} else {
else
// Otherwise, both are negative, so we need to flip the sense of the
// comparison to get the correct result. (This assumes a twos- or ones-
// complement integer representation; if integers are represented in a
// sign-magnitude representation, then this flip is incorrect).
if (aInt > bInt) {
if (aInt > bInt)
LE_LESS
} else if (aInt == bInt) {
else if (aInt == bInt)
LE_EQUAL
} else {
else
LE_GREATER
}
};
;
}
// TODO https://github.com/zig-lang/zig/issues/305
@ -78,23 +76,21 @@ pub extern fn __getf2(a: f128, b: f128) -> c_int {
if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
if ((aAbs | bAbs) == 0) return GE_EQUAL;
return if ((aInt & bInt) >= 0) {
if (aInt < bInt) {
return if ((aInt & bInt) >= 0)
if (aInt < bInt)
GE_LESS
} else if (aInt == bInt) {
else if (aInt == bInt)
GE_EQUAL
} else {
else
GE_GREATER
}
} else {
if (aInt > bInt) {
else
if (aInt > bInt)
GE_LESS
} else if (aInt == bInt) {
else if (aInt == bInt)
GE_EQUAL
} else {
else
GE_GREATER
}
};
;
}
pub extern fn __unordtf2(a: f128, b: f128) -> c_int {

View File

@ -10,7 +10,7 @@ test "global variable alignment" {
assert(@typeOf(slice) == []align(4) u8);
}
fn derp() align(@sizeOf(usize) * 2) -> i32 { 1234 }
fn derp() align(@sizeOf(usize) * 2) -> i32 { return 1234; }
fn noop1() align(1) {}
fn noop4() align(4) {}
@ -53,14 +53,14 @@ test "implicitly decreasing pointer alignment" {
assert(addUnaligned(&a, &b) == 7);
}
fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) -> u32 { *a + *b }
fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) -> u32 { return *a + *b; }
test "implicitly decreasing slice alignment" {
const a: u32 align(4) = 3;
const b: u32 align(8) = 4;
assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
}
fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) -> u32 { a[0] + b[0] }
fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) -> u32 { return a[0] + b[0]; }
test "specifying alignment allows pointer cast" {
testBytesAlign(0x33);
@ -115,20 +115,20 @@ fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) -> i32, answer: i32) {
assert(ptr() == answer);
}
fn alignedSmall() align(8) -> i32 { 1234 }
fn alignedBig() align(16) -> i32 { 5678 }
fn alignedSmall() align(8) -> i32 { return 1234; }
fn alignedBig() align(16) -> i32 { return 5678; }
test "@alignCast functions" {
assert(fnExpectsOnly1(simple4) == 0x19);
}
fn fnExpectsOnly1(ptr: fn()align(1) -> i32) -> i32 {
fnExpects4(@alignCast(4, ptr))
return fnExpects4(@alignCast(4, ptr));
}
fn fnExpects4(ptr: fn()align(4) -> i32) -> i32 {
ptr()
return ptr();
}
fn simple4() align(4) -> i32 { 0x19 }
fn simple4() align(4) -> i32 { return 0x19; }
test "generic function with align param" {
@ -137,7 +137,7 @@ test "generic function with align param" {
assert(whyWouldYouEverDoThis(8) == 0x1);
}
fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) -> u8 { 0x1 }
fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) -> u8 { return 0x1; }
test "@ptrCast preserves alignment of bigger source" {

View File

@ -22,7 +22,7 @@ test "arrays" {
assert(getArrayLen(array) == 5);
}
fn getArrayLen(a: []const u32) -> usize {
a.len
return a.len;
}
test "void arrays" {
@ -41,7 +41,7 @@ test "array literal" {
}
test "array dot len const expr" {
assert(comptime {some_array.len == 4});
assert(comptime x: {break :x some_array.len == 4;});
}
const ArrayDotLenConstExpr = struct {

View File

@ -10,5 +10,5 @@ fn testBitCast_i32_u32() {
assert(conv2(@maxValue(u32)) == -1);
}
fn conv(x: i32) -> u32 { @bitCast(u32, x) }
fn conv2(x: u32) -> i32 { @bitCast(i32, x) }
fn conv(x: i32) -> u32 { return @bitCast(u32, x); }
fn conv2(x: u32) -> i32 { return @bitCast(i32, x); }

View File

@ -22,7 +22,7 @@ test "bool cmp" {
assert(testBoolCmp(true, false) == false);
}
fn testBoolCmp(a: bool, b: bool) -> bool {
a == b
return a == b;
}
const global_f = false;

View File

@ -50,7 +50,7 @@ test "peer resolve arrays of different size to const slice" {
comptime assert(mem.eql(u8, boolToStr(false), "false"));
}
fn boolToStr(b: bool) -> []const u8 {
if (b) "true" else "false"
return if (b) "true" else "false";
}
@ -239,17 +239,17 @@ test "peer type resolution: error and [N]T" {
error BadValue;
fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
switch (x) {
return switch (x) {
0x00 => "OK",
else => error.BadValue,
}
};
}
fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {
switch (x) {
return switch (x) {
0x00 => "OK",
0x01 => "OKK",
else => error.BadValue,
}
};
}
test "explicit cast float number literal to integer if no fraction component" {
@ -269,11 +269,11 @@ fn testCast128() {
}
fn cast128Int(x: f128) -> u128 {
@bitCast(u128, x)
return @bitCast(u128, x);
}
fn cast128Float(x: u128) -> f128 {
@bitCast(f128, x)
return @bitCast(f128, x);
}
test "const slice widen cast" {

View File

@ -7,9 +7,9 @@ error FalseNotAllowed;
fn runSomeErrorDefers(x: bool) -> %bool {
index = 0;
defer {result[index] = 'a'; index += 1;};
%defer {result[index] = 'b'; index += 1;};
defer {result[index] = 'c'; index += 1;};
defer {result[index] = 'a'; index += 1;}
%defer {result[index] = 'b'; index += 1;}
defer {result[index] = 'c'; index += 1;}
return if (x) x else error.FalseNotAllowed;
}
@ -18,9 +18,9 @@ test "mixing normal and error defers" {
assert(result[0] == 'c');
assert(result[1] == 'a');
const ok = runSomeErrorDefers(false) %% |err| {
const ok = runSomeErrorDefers(false) %% |err| x: {
assert(err == error.FalseNotAllowed);
true
break :x true;
};
assert(ok);
assert(result[0] == 'c');
@ -41,5 +41,5 @@ fn testBreakContInDefer(x: usize) {
if (i == 5) break;
}
assert(i == 5);
};
}
}

View File

@ -41,7 +41,7 @@ const Bar = enum {
};
fn returnAnInt(x: i32) -> Foo {
Foo { .One = x }
return Foo { .One = x };
}

View File

@ -8,9 +8,9 @@ const ET = union(enum) {
pub fn print(a: &const ET, buf: []u8) -> %usize {
return switch (*a) {
ET.SINT => |x| { fmt.formatIntBuf(buf, x, 10, false, 0) },
ET.UINT => |x| { fmt.formatIntBuf(buf, x, 10, false, 0) },
}
ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
};
}
};

View File

@ -3,7 +3,7 @@ const mem = @import("std").mem;
pub fn foo() -> %i32 {
const x = %return bar();
return x + 1
return x + 1;
}
pub fn bar() -> %i32 {
@ -21,7 +21,7 @@ test "error wrapping" {
error ItBroke;
fn gimmeItBroke() -> []const u8 {
@errorName(error.ItBroke)
return @errorName(error.ItBroke);
}
test "@errorName" {
@ -48,7 +48,7 @@ error AnError;
error AnError;
error SecondError;
fn shouldBeNotEqual(a: error, b: error) {
if (a == b) unreachable
if (a == b) unreachable;
}
@ -60,11 +60,7 @@ test "error binary operator" {
}
error ItBroke;
fn errBinaryOperatorG(x: bool) -> %isize {
if (x) {
error.ItBroke
} else {
isize(10)
}
return if (x) error.ItBroke else isize(10);
}
@ -72,7 +68,7 @@ test "unwrap simple value from error" {
const i = %%unwrapSimpleValueFromErrorDo();
assert(i == 13);
}
fn unwrapSimpleValueFromErrorDo() -> %isize { 13 }
fn unwrapSimpleValueFromErrorDo() -> %isize { return 13; }
test "error return in assignment" {

View File

@ -44,7 +44,7 @@ test "static function evaluation" {
assert(statically_added_number == 3);
}
const statically_added_number = staticAdd(1, 2);
fn staticAdd(a: i32, b: i32) -> i32 { a + b }
fn staticAdd(a: i32, b: i32) -> i32 { return a + b; }
test "const expr eval on single expr blocks" {
@ -54,10 +54,10 @@ test "const expr eval on single expr blocks" {
fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 {
const literal = 3;
const result = if (b) {
literal
} else {
x
const result = if (b) b: {
break :b literal;
} else b: {
break :b x;
};
return result;
@ -94,9 +94,9 @@ pub const Vec3 = struct {
data: [3]f32,
};
pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 {
Vec3 {
return Vec3 {
.data = []f32 { x, y, z, },
}
};
}
@ -176,7 +176,7 @@ fn max(comptime T: type, a: T, b: T) -> T {
}
}
fn letsTryToCompareBools(a: bool, b: bool) -> bool {
max(bool, a, b)
return max(bool, a, b);
}
test "inlined block and runtime block phi" {
assert(letsTryToCompareBools(true, true));
@ -202,9 +202,9 @@ const cmd_fns = []CmdFn{
CmdFn {.name = "two", .func = two},
CmdFn {.name = "three", .func = three},
};
fn one(value: i32) -> i32 { value + 1 }
fn two(value: i32) -> i32 { value + 2 }
fn three(value: i32) -> i32 { value + 3 }
fn one(value: i32) -> i32 { return value + 1; }
fn two(value: i32) -> i32 { return value + 2; }
fn three(value: i32) -> i32 { return value + 3; }
fn performFn(comptime prefix_char: u8, start_value: i32) -> i32 {
var result: i32 = start_value;
@ -317,12 +317,12 @@ test "create global array with for loop" {
assert(global_array[9] == 9 * 9);
}
const global_array = {
const global_array = x: {
var result: [10]usize = undefined;
for (result) |*item, index| {
*item = index * index;
}
result
break :x result;
};
test "compile-time downcast when the bits fit" {

View File

@ -4,7 +4,7 @@ test "params" {
assert(testParamsAdd(22, 11) == 33);
}
fn testParamsAdd(a: i32, b: i32) -> i32 {
a + b
return a + b;
}
@ -22,7 +22,7 @@ test "void parameters" {
}
fn voidFun(a: i32, b: void, c: i32, d: void) {
const v = b;
const vv: void = if (a == 1) {v} else {};
const vv: void = if (a == 1) v else {};
assert(a + c == 3);
return vv;
}
@ -45,9 +45,9 @@ test "separate block scopes" {
assert(no_conflict == 5);
}
const c = {
const c = x: {
const no_conflict = i32(10);
no_conflict
break :x no_conflict;
};
assert(c == 10);
}
@ -73,7 +73,7 @@ test "implicit cast function unreachable return" {
fn wantsFnWithVoid(f: fn()) { }
fn fnWithUnreachable() -> noreturn {
unreachable
unreachable;
}
@ -83,14 +83,14 @@ test "function pointers" {
assert(f() == u32(i) + 5);
}
}
fn fn1() -> u32 {5}
fn fn2() -> u32 {6}
fn fn3() -> u32 {7}
fn fn4() -> u32 {8}
fn fn1() -> u32 {return 5;}
fn fn2() -> u32 {return 6;}
fn fn3() -> u32 {return 7;}
fn fn4() -> u32 {return 8;}
test "inline function call" {
assert(@inlineCall(add, 3, 9) == 12);
}
fn add(a: i32, b: i32) -> i32 { a + b }
fn add(a: i32, b: i32) -> i32 { return a + b; }

View File

@ -12,7 +12,7 @@ test "continue in for loop" {
}
break;
}
if (sum != 6) unreachable
if (sum != 6) unreachable;
}
test "for loop with pointer elem var" {

View File

@ -11,7 +11,7 @@ fn max(comptime T: type, a: T, b: T) -> T {
}
fn add(comptime a: i32, b: i32) -> i32 {
return (comptime {a}) + b;
return (comptime a) + b;
}
const the_max = max(u32, 1234, 5678);
@ -20,15 +20,15 @@ test "compile time generic eval" {
}
fn gimmeTheBigOne(a: u32, b: u32) -> u32 {
max(u32, a, b)
return max(u32, a, b);
}
fn shouldCallSameInstance(a: u32, b: u32) -> u32 {
max(u32, a, b)
return max(u32, a, b);
}
fn sameButWithFloats(a: f64, b: f64) -> f64 {
max(f64, a, b)
return max(f64, a, b);
}
test "fn with comptime args" {
@ -49,28 +49,28 @@ comptime {
}
fn max_var(a: var, b: var) -> @typeOf(a + b) {
if (a > b) a else b
return if (a > b) a else b;
}
fn max_i32(a: i32, b: i32) -> i32 {
max_var(a, b)
return max_var(a, b);
}
fn max_f64(a: f64, b: f64) -> f64 {
max_var(a, b)
return max_var(a, b);
}
pub fn List(comptime T: type) -> type {
SmallList(T, 8)
return SmallList(T, 8);
}
pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
struct {
return struct {
items: []T,
length: usize,
prealloc_items: [STATIC_SIZE]T,
}
};
}
test "function with return type type" {
@ -91,20 +91,20 @@ test "generic struct" {
assert(b1.getVal());
}
fn GenNode(comptime T: type) -> type {
struct {
return struct {
value: T,
next: ?&GenNode(T),
fn getVal(n: &const GenNode(T)) -> T { n.value }
}
fn getVal(n: &const GenNode(T)) -> T { return n.value; }
};
}
test "const decls in struct" {
assert(GenericDataThing(3).count_plus_one == 4);
}
fn GenericDataThing(comptime count: isize) -> type {
struct {
return struct {
const count_plus_one = count + 1;
}
};
}
@ -120,16 +120,16 @@ test "generic fn with implicit cast" {
assert(getFirstByte(u8, []u8 {13}) == 13);
assert(getFirstByte(u16, []u16 {0, 13}) == 0);
}
fn getByte(ptr: ?&const u8) -> u8 {*??ptr}
fn getByte(ptr: ?&const u8) -> u8 {return *??ptr;}
fn getFirstByte(comptime T: type, mem: []const T) -> u8 {
getByte(@ptrCast(&const u8, &mem[0]))
return getByte(@ptrCast(&const u8, &mem[0]));
}
const foos = []fn(var) -> bool { foo1, foo2 };
fn foo1(arg: var) -> bool { arg }
fn foo2(arg: var) -> bool { !arg }
fn foo1(arg: var) -> bool { return arg; }
fn foo2(arg: var) -> bool { return !arg; }
test "array of generic fns" {
assert(foos[0](true));

View File

@ -29,10 +29,10 @@ test "else if expression" {
}
fn elseIfExpressionF(c: u8) -> u8 {
if (c == 0) {
0
return 0;
} else if (c == 1) {
1
return 1;
} else {
u8(2)
return u8(2);
}
}

View File

@ -1 +1 @@
pub fn foo() -> i32 { 1234 }
pub fn foo() -> i32 { return 1234; }

View File

@ -8,10 +8,10 @@ fn foo(id: u64) -> %i32 {
return %return getErrInt();
},
else => error.ItBroke,
}
};
}
fn getErrInt() -> %i32 { 0 }
fn getErrInt() -> %i32 { return 0; }
error ItBroke;

View File

@ -28,16 +28,16 @@ fn testDivision() {
assert(divTrunc(f32, -5.0, 3.0) == -1.0);
}
fn div(comptime T: type, a: T, b: T) -> T {
a / b
return a / b;
}
fn divExact(comptime T: type, a: T, b: T) -> T {
@divExact(a, b)
return @divExact(a, b);
}
fn divFloor(comptime T: type, a: T, b: T) -> T {
@divFloor(a, b)
return @divFloor(a, b);
}
fn divTrunc(comptime T: type, a: T, b: T) -> T {
@divTrunc(a, b)
return @divTrunc(a, b);
}
test "@addWithOverflow" {
@ -71,7 +71,7 @@ fn testClz() {
}
fn clz(x: var) -> usize {
@clz(x)
return @clz(x);
}
test "@ctz" {
@ -86,7 +86,7 @@ fn testCtz() {
}
fn ctz(x: var) -> usize {
@ctz(x)
return @ctz(x);
}
test "assignment operators" {
@ -180,10 +180,10 @@ fn test_u64_div() {
assert(result.remainder == 100663296);
}
fn divWithResult(a: u64, b: u64) -> DivResult {
DivResult {
return DivResult {
.quotient = a / b,
.remainder = a % b,
}
};
}
const DivResult = struct {
quotient: u64,
@ -191,8 +191,8 @@ const DivResult = struct {
};
test "binary not" {
assert(comptime {~u16(0b1010101010101010) == 0b0101010101010101});
assert(comptime {~u64(2147483647) == 18446744071562067968});
assert(comptime x: {break :x ~u16(0b1010101010101010) == 0b0101010101010101;});
assert(comptime x: {break :x ~u64(2147483647) == 18446744071562067968;});
testBinaryNot(0b1010101010101010);
}
@ -331,7 +331,7 @@ test "f128" {
comptime test_f128();
}
fn make_f128(x: f128) -> f128 { x }
fn make_f128(x: f128) -> f128 { return x; }
fn test_f128() {
assert(@sizeOf(f128) == 16);

View File

@ -110,17 +110,17 @@ fn testShortCircuit(f: bool, t: bool) {
var hit_3 = f;
var hit_4 = f;
if (t or {assert(f); f}) {
if (t or x: {assert(f); break :x f;}) {
hit_1 = t;
}
if (f or { hit_2 = t; f }) {
if (f or x: { hit_2 = t; break :x f; }) {
assert(f);
}
if (t and { hit_3 = t; f }) {
if (t and x: { hit_3 = t; break :x f; }) {
assert(f);
}
if (f and {assert(f); f}) {
if (f and x: {assert(f); break :x f;}) {
assert(f);
} else {
hit_4 = t;
@ -135,11 +135,11 @@ test "truncate" {
assert(testTruncate(0x10fd) == 0xfd);
}
fn testTruncate(x: u32) -> u8 {
@truncate(u8, x)
return @truncate(u8, x);
}
fn first4KeysOfHomeRow() -> []const u8 {
"aoeu"
return "aoeu";
}
test "return string from function" {
@ -167,7 +167,7 @@ test "memcpy and memset intrinsics" {
}
test "builtin static eval" {
const x : i32 = comptime {1 + 2 + 3};
const x : i32 = comptime x: {break :x 1 + 2 + 3;};
assert(x == comptime 6);
}
@ -190,7 +190,7 @@ test "slicing" {
test "constant equal function pointers" {
const alias = emptyFn;
assert(comptime {emptyFn == alias});
assert(comptime x: {break :x emptyFn == alias;});
}
fn emptyFn() {}
@ -280,14 +280,14 @@ test "cast small unsigned to larger signed" {
assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
}
fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x }
fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x }
fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { return x; }
fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { return x; }
test "implicit cast after unreachable" {
assert(outer() == 1234);
}
fn inner() -> i32 { 1234 }
fn inner() -> i32 { return 1234; }
fn outer() -> i64 {
return inner();
}
@ -310,8 +310,8 @@ test "call result of if else expression" {
fn f2(x: bool) -> []const u8 {
return (if (x) fA else fB)();
}
fn fA() -> []const u8 { "a" }
fn fB() -> []const u8 { "b" }
fn fA() -> []const u8 { return "a"; }
fn fB() -> []const u8 { return "b"; }
test "const expression eval handling of variables" {
@ -379,7 +379,7 @@ test "pointer comparison" {
assert(ptrEql(b, b));
}
fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool {
a == b
return a == b;
}
@ -483,7 +483,7 @@ test "@typeId" {
assert(@typeId(AUnion) == Tid.Union);
assert(@typeId(fn()) == Tid.Fn);
assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
assert(@typeId(@typeOf({this})) == Tid.Block);
assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);
// TODO bound fn
// TODO arg tuple
// TODO opaque

View File

@ -22,7 +22,7 @@ test "reflection: function return type, var args, and param types" {
}
}
fn dummy(a: bool, b: i32, c: f32) -> i32 { 1234 }
fn dummy(a: bool, b: i32, c: f32) -> i32 { return 1234; }
fn dummy_varargs(args: ...) {}
test "reflection: struct member types and names" {

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