Bitcast string
This commit is contained in:
parent
887bcc676c
commit
c56e80d30c
@ -3863,6 +3863,7 @@ pub const Instruction = union(enum) {
|
|||||||
error_union_type_int_to_pointer,
|
error_union_type_int_to_pointer,
|
||||||
error_union_type_upcast,
|
error_union_type_upcast,
|
||||||
error_union_type_downcast,
|
error_union_type_downcast,
|
||||||
|
array_bitcast_to_integer,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4708,6 +4709,36 @@ pub const Builder = struct {
|
|||||||
.type => |type_index| {
|
.type => |type_index| {
|
||||||
const cast_id = try builder.resolveCast(unit, context, type_index, v);
|
const cast_id = try builder.resolveCast(unit, context, type_index, v);
|
||||||
switch (cast_id) {
|
switch (cast_id) {
|
||||||
|
.array_bitcast_to_integer => switch (v.value) {
|
||||||
|
.@"comptime" => |ct| switch (ct) {
|
||||||
|
.constant_array => |constant_array_index| {
|
||||||
|
const constant_array = unit.constant_arrays.get(constant_array_index);
|
||||||
|
const array_type = unit.types.get(constant_array.type).array;
|
||||||
|
switch (array_type.type) {
|
||||||
|
.u8 => {
|
||||||
|
var value: u64 = 0;
|
||||||
|
_ = &value;
|
||||||
|
for (constant_array.values, 0..) |array_value, i| {
|
||||||
|
value |= array_value.constant_int.value << @as(u6, @intCast(i * 8));
|
||||||
|
}
|
||||||
|
return V{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.constant_int = .{
|
||||||
|
.value = value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = type_index,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
const instruction = try unit.instructions.append(context.my_allocator, .{
|
const instruction = try unit.instructions.append(context.my_allocator, .{
|
||||||
.cast = .{
|
.cast = .{
|
||||||
@ -5359,6 +5390,18 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
return .pointer_to_int;
|
return .pointer_to_int;
|
||||||
},
|
},
|
||||||
|
.array => |source_array| {
|
||||||
|
const array_size = source_array.count * unit.types.get(source_array.type).getAbiSize(unit);
|
||||||
|
if (destination_integer.bit_count % 8 != 0) {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
const destination_byte_count = @divExact(destination_integer.bit_count, 8);
|
||||||
|
if (destination_byte_count == array_size) {
|
||||||
|
return .array_bitcast_to_integer;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
},
|
},
|
||||||
.@"error" => |_| switch (source_type.*) {
|
.@"error" => |_| switch (source_type.*) {
|
||||||
@ -9859,7 +9902,39 @@ pub const Builder = struct {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: is this right? .right
|
const left_node = unit.getNode(node.left);
|
||||||
|
switch (left_node.id) {
|
||||||
|
.string_literal => {
|
||||||
|
const string_literal = try unit.fixupStringLiteral(context, left_node.token);
|
||||||
|
var values = try UnpinnedArray(V.Comptime).initialize_with_capacity(context.my_allocator, @intCast(string_literal.len));
|
||||||
|
|
||||||
|
for (string_literal) |b| {
|
||||||
|
values.append_with_capacity(V.Comptime{
|
||||||
|
.constant_int = .{
|
||||||
|
.value = b,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const array_type = try unit.getArrayType(context, .{
|
||||||
|
.count = string_literal.len,
|
||||||
|
.type = .u8,
|
||||||
|
.termination = .none,
|
||||||
|
});
|
||||||
|
|
||||||
|
return V{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.constant_array = try unit.constant_arrays.append(context.my_allocator, .{
|
||||||
|
.values = values.slice(),
|
||||||
|
.type = array_type,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = array_type,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => {
|
||||||
const pointer_value = try builder.resolveRuntimeValue(unit, context, pointer_type_expect, node.left, .right);
|
const pointer_value = try builder.resolveRuntimeValue(unit, context, pointer_type_expect, node.left, .right);
|
||||||
|
|
||||||
break :block switch (side) {
|
break :block switch (side) {
|
||||||
@ -9892,6 +9967,8 @@ pub const Builder = struct {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
.compare_equal,
|
.compare_equal,
|
||||||
.compare_not_equal,
|
.compare_not_equal,
|
||||||
.compare_greater,
|
.compare_greater,
|
||||||
|
@ -2693,6 +2693,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
const cast_instruction = llvm.builder.createCast(cast_type, value, value.getType(), cast_name.ptr, cast_name.len) orelse return LLVM.Value.Instruction.Error.cast;
|
const cast_instruction = llvm.builder.createCast(cast_type, value, value.getType(), cast_name.ptr, cast_name.len) orelse return LLVM.Value.Instruction.Error.cast;
|
||||||
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, cast_instruction);
|
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, cast_instruction);
|
||||||
},
|
},
|
||||||
|
.array_bitcast_to_integer => unreachable,
|
||||||
// TODO: Poke metadata
|
// TODO: Poke metadata
|
||||||
.pointer_var_to_const,
|
.pointer_var_to_const,
|
||||||
.slice_var_to_const,
|
.slice_var_to_const,
|
||||||
|
6
test/standalone/bitcast_string/main.nat
Normal file
6
test/standalone/bitcast_string/main.nat
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const std = #import("std");
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
const main = fn () *!void {
|
||||||
|
const a: u64 = #cast("comptime".@);
|
||||||
|
try expect(a == 7308613719115525987);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user