implement assert builtin
This commit is contained in:
parent
4b5a2460af
commit
13606f7d56
@ -1024,6 +1024,7 @@ pub const Mutability = enum(u1) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const IntrinsicId = enum{
|
pub const IntrinsicId = enum{
|
||||||
|
assert,
|
||||||
@"asm", //this is processed separately as it need special parsing
|
@"asm", //this is processed separately as it need special parsing
|
||||||
cast,
|
cast,
|
||||||
enum_to_int,
|
enum_to_int,
|
||||||
@ -1455,6 +1456,37 @@ pub const Builder = struct {
|
|||||||
_ = expected_type; // autofix
|
_ = expected_type; // autofix
|
||||||
unreachable;
|
unreachable;
|
||||||
},
|
},
|
||||||
|
.assert => {
|
||||||
|
assert(argument_node_list.len == 1);
|
||||||
|
const boolean = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .bool }, argument_node_list[0], .right);
|
||||||
|
switch (boolean.value) {
|
||||||
|
.@"comptime" => |ct| switch (ct) {
|
||||||
|
.bool => |value| switch (value) {
|
||||||
|
true => {},
|
||||||
|
false => {
|
||||||
|
@panic("Assert failed at comptime");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
.runtime => |instruction_index| {
|
||||||
|
const true_block = try builder.newBasicBlock(unit, context);
|
||||||
|
const false_block = try builder.newBasicBlock(unit, context);
|
||||||
|
|
||||||
|
try builder.branch(unit, context, instruction_index, true_block, false_block);
|
||||||
|
|
||||||
|
builder.current_basic_block = false_block;
|
||||||
|
const unreachable_instruction = try unit.instructions.append(context.allocator, .@"unreachable");
|
||||||
|
// TODO: terminate block properly
|
||||||
|
try builder.appendInstruction(unit, context, unreachable_instruction);
|
||||||
|
|
||||||
|
builder.current_basic_block = true_block;
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4228,6 +4260,42 @@ pub const Builder = struct {
|
|||||||
.type = .u8,
|
.type = .u8,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
.boolean_not => blk: {
|
||||||
|
switch (type_expect) {
|
||||||
|
.none => {},
|
||||||
|
.type => |type_index| assert(type_index == .bool),
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
const boolean = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .bool }, node.left, .right);
|
||||||
|
switch (boolean.value) {
|
||||||
|
.runtime => {
|
||||||
|
const xor = try unit.instructions.append(context.allocator, .{
|
||||||
|
.integer_binary_operation = .{
|
||||||
|
.id = .bit_xor,
|
||||||
|
.signedness = .unsigned,
|
||||||
|
.left = boolean,
|
||||||
|
.right = .{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.bool = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = .bool,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, xor);
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.value = .{
|
||||||
|
.runtime = xor,
|
||||||
|
},
|
||||||
|
.type = .bool,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
7
test/standalone/assert/main.nat
Normal file
7
test/standalone/assert/main.nat
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const main = fn() s32 {
|
||||||
|
#assert(true);
|
||||||
|
var a: s32 = 1;
|
||||||
|
const is_not_one = a != 1;
|
||||||
|
#assert(!is_not_one);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user