mirror of
https://github.com/ziglang/zig.git
synced 2026-02-09 11:03:30 +00:00
stage2: implement bitwise expr and error literals
This commit is contained in:
parent
da731e18c9
commit
1f5617ac07
@ -1599,7 +1599,7 @@ pub const SrcLoc = struct {
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
return token_starts[tok_index];
|
||||
},
|
||||
.node_offset => |node_off| {
|
||||
.node_offset, .node_offset_bin_op => |node_off| {
|
||||
const decl = src_loc.container.decl;
|
||||
const node = decl.relativeToNodeIndex(node_off);
|
||||
const tree = decl.container.file_scope.base.tree();
|
||||
@ -1660,9 +1660,28 @@ pub const SrcLoc = struct {
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
return token_starts[tok_index];
|
||||
},
|
||||
.node_offset_bin_op => @panic("TODO"),
|
||||
.node_offset_bin_lhs => @panic("TODO"),
|
||||
.node_offset_bin_rhs => @panic("TODO"),
|
||||
.node_offset_bin_lhs => |node_off| {
|
||||
const decl = src_loc.container.decl;
|
||||
const node = decl.relativeToNodeIndex(node_off);
|
||||
const tree = decl.container.file_scope.base.tree();
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
const src_node = node_datas[node].lhs;
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const tok_index = main_tokens[src_node];
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
return token_starts[tok_index];
|
||||
},
|
||||
.node_offset_bin_rhs => |node_off| {
|
||||
const decl = src_loc.container.decl;
|
||||
const node = decl.relativeToNodeIndex(node_off);
|
||||
const tree = decl.container.file_scope.base.tree();
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
const src_node = node_datas[node].rhs;
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const tok_index = main_tokens[src_node];
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
return token_starts[tok_index];
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
76
src/Sema.zig
76
src/Sema.zig
@ -133,9 +133,9 @@ pub fn analyzeBody(
|
||||
.as_node => try sema.zirAsNode(block, inst),
|
||||
.@"asm" => try sema.zirAsm(block, inst, false),
|
||||
.asm_volatile => try sema.zirAsm(block, inst, true),
|
||||
.bit_and => try sema.zirBitwise(block, inst),
|
||||
.bit_and => try sema.zirBitwise(block, inst, .bit_and),
|
||||
.bit_not => try sema.zirBitNot(block, inst),
|
||||
.bit_or => try sema.zirBitwise(block, inst),
|
||||
.bit_or => try sema.zirBitwise(block, inst, .bit_or),
|
||||
.bitcast => try sema.zirBitcast(block, inst),
|
||||
.bitcast_ref => try sema.zirBitcastRef(block, inst),
|
||||
.bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),
|
||||
@ -227,7 +227,7 @@ pub fn analyzeBody(
|
||||
.subwrap => try sema.zirArithmetic(block, inst),
|
||||
.typeof => try sema.zirTypeof(block, inst),
|
||||
.typeof_peer => try sema.zirTypeofPeer(block, inst),
|
||||
.xor => try sema.zirBitwise(block, inst),
|
||||
.xor => try sema.zirBitwise(block, inst, .xor),
|
||||
// TODO
|
||||
//.switchbr => try sema.zirSwitchBr(block, inst, false),
|
||||
//.switchbr_ref => try sema.zirSwitchBr(block, inst, true),
|
||||
@ -1390,23 +1390,28 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
|
||||
const error_union = try sema.resolveType(block, .unneeded, bin_inst.lhs);
|
||||
const payload = try sema.resolveType(block, .unneeded, bin_inst.rhs);
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
|
||||
const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
|
||||
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
|
||||
const error_union = try sema.resolveType(block, lhs_src, extra.lhs);
|
||||
const payload = try sema.resolveType(block, rhs_src, extra.rhs);
|
||||
|
||||
if (error_union.zigTypeTag() != .ErrorSet) {
|
||||
return sema.mod.fail(&block.base, .todo, "expected error set type, found {}", .{error_union.elemType()});
|
||||
return sema.mod.fail(&block.base, lhs_src, "expected error set type, found {}", .{
|
||||
error_union.elemType(),
|
||||
});
|
||||
}
|
||||
const err_union_ty = try sema.mod.errorUnionType(sema.arena, error_union, payload);
|
||||
|
||||
return sema.mod.constType(sema.arena, .unneeded, err_union_ty);
|
||||
return sema.mod.constType(sema.arena, src, err_union_ty);
|
||||
}
|
||||
|
||||
fn zirErrorSet(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (true) @panic("TODO update zirErrorSet in zir-memory-layout branch");
|
||||
if (true) @panic("TODO update for zir-memory-layout branch");
|
||||
|
||||
// The owner Decl arena will store the hashmap.
|
||||
var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
|
||||
@ -1459,19 +1464,21 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (true) @panic("TODO update zirMergeErrorSets in zir-memory-layout branch");
|
||||
|
||||
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
|
||||
const lhs_ty = try sema.resolveType(block, .unneeded, bin_inst.lhs);
|
||||
const rhs_ty = try sema.resolveType(block, .unneeded, bin_inst.rhs);
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
|
||||
const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
|
||||
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
|
||||
const lhs_ty = try sema.resolveType(block, lhs_src, extra.lhs);
|
||||
const rhs_ty = try sema.resolveType(block, rhs_src, extra.rhs);
|
||||
if (rhs_ty.zigTypeTag() != .ErrorSet)
|
||||
return sema.mod.fail(&block.base, inst.positionals.rhs.src, "expected error set type, found {}", .{rhs_ty});
|
||||
return sema.mod.fail(&block.base, rhs_src, "expected error set type, found {}", .{rhs_ty});
|
||||
if (lhs_ty.zigTypeTag() != .ErrorSet)
|
||||
return sema.mod.fail(&block.base, inst.positionals.lhs.src, "expected error set type, found {}", .{lhs_ty});
|
||||
return sema.mod.fail(&block.base, lhs_src, "expected error set type, found {}", .{lhs_ty});
|
||||
|
||||
// anything merged with anyerror is anyerror
|
||||
if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror)
|
||||
return sema.mod.constInst(sema.arena, inst.base.src, .{
|
||||
return sema.mod.constInst(sema.arena, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.anyerror_type),
|
||||
});
|
||||
@ -1533,7 +1540,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
|
||||
});
|
||||
payload.data.decl = new_decl;
|
||||
|
||||
return sema.analyzeDeclVal(block, inst.base.src, new_decl);
|
||||
return sema.analyzeDeclVal(block, src, new_decl);
|
||||
}
|
||||
|
||||
fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
|
||||
@ -2442,21 +2449,27 @@ fn zirShr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In
|
||||
return sema.mod.fail(&block.base, sema.src, "TODO implement zirShr", .{});
|
||||
}
|
||||
|
||||
fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
|
||||
fn zirBitwise(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
inst: zir.Inst.Index,
|
||||
ir_tag: ir.Inst.Tag,
|
||||
) InnerError!*Inst {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (true) @panic("TODO rework with zir-memory-layout in mind");
|
||||
|
||||
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
|
||||
const src: LazySrcLoc = .todo;
|
||||
const lhs = try sema.resolveInst(bin_inst.lhs);
|
||||
const rhs = try sema.resolveInst(bin_inst.rhs);
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
|
||||
const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
|
||||
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
|
||||
const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const lhs = try sema.resolveInst(extra.lhs);
|
||||
const rhs = try sema.resolveInst(extra.rhs);
|
||||
|
||||
const instructions = &[_]*Inst{ lhs, rhs };
|
||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
|
||||
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src);
|
||||
const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src);
|
||||
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
|
||||
const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
|
||||
|
||||
const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
|
||||
resolved_type.elemType()
|
||||
@ -2499,13 +2512,6 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
const ir_tag = switch (inst.base.tag) {
|
||||
.bit_and => Inst.Tag.bit_and,
|
||||
.bit_or => Inst.Tag.bit_or,
|
||||
.xor => Inst.Tag.xor,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);
|
||||
}
|
||||
|
||||
|
||||
@ -367,6 +367,9 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
|
||||
.array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),
|
||||
.array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),
|
||||
|
||||
.error_union => return simpleBinOp(mod, scope, rl, node, .error_union_type),
|
||||
.merge_error_sets => return simpleBinOp(mod, scope, rl, node, .merge_error_sets),
|
||||
|
||||
.bool_and => return boolBinOp(mod, scope, rl, node, .bool_br_and),
|
||||
.bool_or => return boolBinOp(mod, scope, rl, node, .bool_br_or),
|
||||
|
||||
@ -515,40 +518,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
|
||||
const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
|
||||
return blockExpr(mod, scope, rl, node, statements);
|
||||
},
|
||||
.enum_literal => {
|
||||
const ident_token = main_tokens[node];
|
||||
const string_bytes = &gz.zir_code.string_bytes;
|
||||
const str_index = @intCast(u32, string_bytes.items.len);
|
||||
try mod.appendIdentStr(scope, ident_token, string_bytes);
|
||||
try string_bytes.append(mod.gpa, 0);
|
||||
const result = try gz.addStrTok(.enum_literal, str_index, ident_token);
|
||||
return rvalue(mod, scope, rl, result, node);
|
||||
},
|
||||
.error_value => {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const ident_token = node_datas[node].rhs;
|
||||
const name = try mod.identifierTokenString(scope, ident_token);
|
||||
const result = try addZirInstTag(mod, scope, src, .error_value, .{ .name = name });
|
||||
return rvalue(mod, scope, rl, result);
|
||||
},
|
||||
.error_union => {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const error_set = try typeExpr(mod, scope, node_datas[node].lhs);
|
||||
const payload = try typeExpr(mod, scope, node_datas[node].rhs);
|
||||
const result = try addZIRBinOp(mod, scope, src, .error_union_type, error_set, payload);
|
||||
return rvalue(mod, scope, rl, result);
|
||||
},
|
||||
.merge_error_sets => {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const lhs = try typeExpr(mod, scope, node_datas[node].lhs);
|
||||
const rhs = try typeExpr(mod, scope, node_datas[node].rhs);
|
||||
const result = try addZIRBinOp(mod, scope, src, .merge_error_sets, lhs, rhs);
|
||||
return rvalue(mod, scope, rl, result);
|
||||
},
|
||||
.enum_literal => return simpleStrTok(mod, scope, rl, main_tokens[node], node, .enum_literal),
|
||||
.error_value => return simpleStrTok(mod, scope, rl, node_datas[node].rhs, node, .error_value),
|
||||
.anyframe_literal => return mod.failNode(scope, node, "async and related features are not yet supported", .{}),
|
||||
.anyframe_type => return mod.failNode(scope, node, "async and related features are not yet supported", .{}),
|
||||
.@"catch" => {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const catch_token = main_tokens[node];
|
||||
const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
|
||||
catch_token + 2
|
||||
@ -1597,7 +1571,6 @@ fn containerDecl(
|
||||
rl: ResultLoc,
|
||||
container_decl: ast.full.ContainerDecl,
|
||||
) InnerError!zir.Inst.Ref {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
return mod.failTok(scope, container_decl.ast.main_token, "TODO implement container decls", .{});
|
||||
}
|
||||
|
||||
@ -1607,8 +1580,9 @@ fn errorSetDecl(
|
||||
rl: ResultLoc,
|
||||
node: ast.Node.Index,
|
||||
) InnerError!zir.Inst.Ref {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const tree = scope.tree();
|
||||
if (true) @panic("TODO update for zir-memory-layout branch");
|
||||
const gz = scope.getGenZir();
|
||||
const tree = gz.tree();
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const token_tags = tree.tokens.items(.tag);
|
||||
|
||||
@ -1905,6 +1879,23 @@ fn simpleBinOp(
|
||||
return rvalue(mod, scope, rl, result, node);
|
||||
}
|
||||
|
||||
fn simpleStrTok(
|
||||
mod: *Module,
|
||||
scope: *Scope,
|
||||
rl: ResultLoc,
|
||||
ident_token: ast.TokenIndex,
|
||||
node: ast.Node.Index,
|
||||
op_inst_tag: zir.Inst.Tag,
|
||||
) InnerError!zir.Inst.Ref {
|
||||
const gz = scope.getGenZir();
|
||||
const string_bytes = &gz.zir_code.string_bytes;
|
||||
const str_index = @intCast(u32, string_bytes.items.len);
|
||||
try mod.appendIdentStr(scope, ident_token, string_bytes);
|
||||
try string_bytes.append(mod.gpa, 0);
|
||||
const result = try gz.addStrTok(op_inst_tag, str_index, ident_token);
|
||||
return rvalue(mod, scope, rl, result, node);
|
||||
}
|
||||
|
||||
fn boolBinOp(
|
||||
mod: *Module,
|
||||
scope: *Scope,
|
||||
|
||||
15
src/zir.zig
15
src/zir.zig
@ -312,8 +312,12 @@ pub const Inst = struct {
|
||||
/// Uses the `un_node` field.
|
||||
ensure_result_non_error,
|
||||
/// Create a `E!T` type.
|
||||
/// Uses the `pl_node` field with `Bin` payload.
|
||||
error_union_type,
|
||||
/// Create an error set. extra[lhs..rhs]. The values are token index offsets.
|
||||
/// Create an error set. TODO can't we just do this in astgen? reconsider
|
||||
/// memory layout of error sets. if astgen wants to make Sema do the work,
|
||||
/// this ZIR instruction could just be an AST node index. If astgen wants to
|
||||
/// do the work, it could use a const instruction.
|
||||
error_set,
|
||||
/// `error.Foo` syntax. Uses the `str_tok` field of the Data union.
|
||||
error_value,
|
||||
@ -393,6 +397,7 @@ pub const Inst = struct {
|
||||
/// Uses the `node` field.
|
||||
repeat_inline,
|
||||
/// Merge two error sets into one, `E1 || E2`.
|
||||
/// Uses the `pl_node` field with payload `Bin`.
|
||||
merge_error_sets,
|
||||
/// Ambiguously remainder division or modulus. If the computation would possibly have
|
||||
/// a different value depending on whether the operation is remainder division or modulus,
|
||||
@ -1368,14 +1373,11 @@ const Writer = struct {
|
||||
try stream.print("= {s}(", .{@tagName(tags[inst])});
|
||||
switch (tag) {
|
||||
.array_type,
|
||||
.bit_and,
|
||||
.bit_or,
|
||||
.as,
|
||||
.coerce_result_ptr,
|
||||
.elem_ptr,
|
||||
.elem_val,
|
||||
.intcast,
|
||||
.merge_error_sets,
|
||||
.store,
|
||||
.store_to_block_ptr,
|
||||
=> try self.writeBin(stream, inst),
|
||||
@ -1481,6 +1483,10 @@ const Writer = struct {
|
||||
.shr,
|
||||
.xor,
|
||||
.store_node,
|
||||
.error_union_type,
|
||||
.merge_error_sets,
|
||||
.bit_and,
|
||||
.bit_or,
|
||||
=> try self.writePlNodeBin(stream, inst),
|
||||
|
||||
.call,
|
||||
@ -1530,7 +1536,6 @@ const Writer = struct {
|
||||
.bitcast,
|
||||
.bitcast_ref,
|
||||
.bitcast_result_ptr,
|
||||
.error_union_type,
|
||||
.error_set,
|
||||
.store_to_inferred_ptr,
|
||||
=> try stream.writeAll("TODO)"),
|
||||
|
||||
@ -184,103 +184,103 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
);
|
||||
|
||||
// Bitwise And
|
||||
//case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ print(8, 9);
|
||||
// \\ print(3, 7);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\
|
||||
// \\fn print(a: u32, b: u32) void {
|
||||
// \\ asm volatile ("svc #0"
|
||||
// \\ :
|
||||
// \\ : [number] "{r7}" (4),
|
||||
// \\ [arg3] "{r2}" (a & b),
|
||||
// \\ [arg1] "{r0}" (1),
|
||||
// \\ [arg2] "{r1}" (@ptrToInt("123456789"))
|
||||
// \\ : "memory"
|
||||
// \\ );
|
||||
// \\ return;
|
||||
// \\}
|
||||
// \\
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("svc #0"
|
||||
// \\ :
|
||||
// \\ : [number] "{r7}" (1),
|
||||
// \\ [arg1] "{r0}" (0)
|
||||
// \\ : "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
//,
|
||||
// "12345678123",
|
||||
//);
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ print(8, 9);
|
||||
\\ print(3, 7);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\
|
||||
\\fn print(a: u32, b: u32) void {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (4),
|
||||
\\ [arg3] "{r2}" (a & b),
|
||||
\\ [arg1] "{r0}" (1),
|
||||
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ return;
|
||||
\\}
|
||||
\\
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (1),
|
||||
\\ [arg1] "{r0}" (0)
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"12345678123",
|
||||
);
|
||||
|
||||
// Bitwise Or
|
||||
//case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ print(4, 2);
|
||||
// \\ print(3, 7);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\
|
||||
// \\fn print(a: u32, b: u32) void {
|
||||
// \\ asm volatile ("svc #0"
|
||||
// \\ :
|
||||
// \\ : [number] "{r7}" (4),
|
||||
// \\ [arg3] "{r2}" (a | b),
|
||||
// \\ [arg1] "{r0}" (1),
|
||||
// \\ [arg2] "{r1}" (@ptrToInt("123456789"))
|
||||
// \\ : "memory"
|
||||
// \\ );
|
||||
// \\ return;
|
||||
// \\}
|
||||
// \\
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("svc #0"
|
||||
// \\ :
|
||||
// \\ : [number] "{r7}" (1),
|
||||
// \\ [arg1] "{r0}" (0)
|
||||
// \\ : "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
//,
|
||||
// "1234561234567",
|
||||
//);
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ print(4, 2);
|
||||
\\ print(3, 7);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\
|
||||
\\fn print(a: u32, b: u32) void {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (4),
|
||||
\\ [arg3] "{r2}" (a | b),
|
||||
\\ [arg1] "{r0}" (1),
|
||||
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ return;
|
||||
\\}
|
||||
\\
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (1),
|
||||
\\ [arg1] "{r0}" (0)
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"1234561234567",
|
||||
);
|
||||
|
||||
// Bitwise Xor
|
||||
//case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ print(42, 42);
|
||||
// \\ print(3, 5);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\
|
||||
// \\fn print(a: u32, b: u32) void {
|
||||
// \\ asm volatile ("svc #0"
|
||||
// \\ :
|
||||
// \\ : [number] "{r7}" (4),
|
||||
// \\ [arg3] "{r2}" (a ^ b),
|
||||
// \\ [arg1] "{r0}" (1),
|
||||
// \\ [arg2] "{r1}" (@ptrToInt("123456789"))
|
||||
// \\ : "memory"
|
||||
// \\ );
|
||||
// \\ return;
|
||||
// \\}
|
||||
// \\
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("svc #0"
|
||||
// \\ :
|
||||
// \\ : [number] "{r7}" (1),
|
||||
// \\ [arg1] "{r0}" (0)
|
||||
// \\ : "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
//,
|
||||
// "123456",
|
||||
//);
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ print(42, 42);
|
||||
\\ print(3, 5);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\
|
||||
\\fn print(a: u32, b: u32) void {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (4),
|
||||
\\ [arg3] "{r2}" (a ^ b),
|
||||
\\ [arg1] "{r0}" (1),
|
||||
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ return;
|
||||
\\}
|
||||
\\
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (1),
|
||||
\\ [arg1] "{r0}" (0)
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"123456",
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@ -1356,53 +1356,53 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\}
|
||||
, &[_][]const u8{":8:21: error: evaluation exceeded 1000 backwards branches"});
|
||||
}
|
||||
//{
|
||||
// var case = ctx.exe("orelse at comptime", linux_x64);
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const i: ?u64 = 0;
|
||||
// \\ const orelsed = i orelse 5;
|
||||
// \\ assert(orelsed == 0);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable;
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// ,
|
||||
// "",
|
||||
// );
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const i: ?u64 = null;
|
||||
// \\ const orelsed = i orelse 5;
|
||||
// \\ assert(orelsed == 5);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable;
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// ,
|
||||
// "",
|
||||
// );
|
||||
//}
|
||||
{
|
||||
var case = ctx.exe("orelse at comptime", linux_x64);
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ const i: ?u64 = 0;
|
||||
\\ const orelsed = i orelse 5;
|
||||
\\ assert(orelsed == 0);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn assert(b: bool) void {
|
||||
\\ if (!b) unreachable;
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ const i: ?u64 = null;
|
||||
\\ const orelsed = i orelse 5;
|
||||
\\ assert(orelsed == 5);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn assert(b: bool) void {
|
||||
\\ if (!b) unreachable;
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
var case = ctx.exe("only 1 function and it gets updated", linux_x64);
|
||||
@ -1454,113 +1454,117 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
"",
|
||||
);
|
||||
}
|
||||
//{
|
||||
// var case = ctx.exe("catch at comptime", linux_x64);
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const i: anyerror!u64 = 0;
|
||||
// \\ const caught = i catch 5;
|
||||
// \\ assert(caught == 0);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable;
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// ,
|
||||
// "",
|
||||
// );
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const i: anyerror!u64 = error.B;
|
||||
// \\ const caught = i catch 5;
|
||||
// \\ assert(caught == 5);
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable;
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// ,
|
||||
// "",
|
||||
// );
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const a: anyerror!comptime_int = 42;
|
||||
// \\ const b: *const comptime_int = &(a catch unreachable);
|
||||
// \\ assert(b.* == 42);
|
||||
// \\
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable; // assertion failure
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// , "");
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\const a: anyerror!u32 = error.B;
|
||||
// \\_ = &(a catch |err| assert(err == error.B));
|
||||
// \\exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable;
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// , "");
|
||||
// case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const a: anyerror!u32 = error.Bar;
|
||||
// \\ a catch |err| assert(err == error.Bar);
|
||||
// \\
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable;
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
// , "");
|
||||
//}
|
||||
{
|
||||
var case = ctx.exe("catch at comptime", linux_x64);
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ const i: anyerror!u64 = 0;
|
||||
\\ const caught = i catch 5;
|
||||
\\ assert(caught == 0);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn assert(b: bool) void {
|
||||
\\ if (!b) unreachable;
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ const i: anyerror!u64 = error.B;
|
||||
\\ const caught = i catch 5;
|
||||
\\ assert(caught == 5);
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn assert(b: bool) void {
|
||||
\\ if (!b) unreachable;
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
|
||||
//case.addCompareOutput(
|
||||
// \\export fn _start() noreturn {
|
||||
// \\ const a: anyerror!comptime_int = 42;
|
||||
// \\ const b: *const comptime_int = &(a catch unreachable);
|
||||
// \\ assert(b.* == 42);
|
||||
// \\
|
||||
// \\ exit();
|
||||
// \\}
|
||||
// \\fn assert(b: bool) void {
|
||||
// \\ if (!b) unreachable; // assertion failure
|
||||
// \\}
|
||||
// \\fn exit() noreturn {
|
||||
// \\ asm volatile ("syscall"
|
||||
// \\ :
|
||||
// \\ : [number] "{rax}" (231),
|
||||
// \\ [arg1] "{rdi}" (0)
|
||||
// \\ : "rcx", "r11", "memory"
|
||||
// \\ );
|
||||
// \\ unreachable;
|
||||
// \\}
|
||||
//, "");
|
||||
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ const a: anyerror!u32 = error.B;
|
||||
\\ _ = &(a catch |err| assert(err == error.B));
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn assert(b: bool) void {
|
||||
\\ if (!b) unreachable;
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ const a: anyerror!u32 = error.Bar;
|
||||
\\ a catch |err| assert(err == error.Bar);
|
||||
\\
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn assert(b: bool) void {
|
||||
\\ if (!b) unreachable;
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
//{
|
||||
// var case = ctx.exe("merge error sets", linux_x64);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user