Merge pull request #74 from birth-software/array-pointer

Fix pointer to array issue
This commit is contained in:
David 2024-02-12 19:57:59 -06:00 committed by GitHub
commit f8bd7ad443
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 130 additions and 5 deletions

View File

@ -3764,6 +3764,22 @@ pub const Builder = struct {
true => unreachable,
false => switch (unit.types.get(pointer.type).*) {
.array => |array| {
const pointer_gep = try unit.instructions.append(context.allocator, .{
.get_element_pointer = .{
.pointer = expression_to_slice.value.runtime,
.base_type = array.type,
.index = range_start,
},
});
try builder.appendInstruction(unit, context, pointer_gep);
const pointer_type = try unit.getPointerType(context, .{
.type = array.type,
.termination = .none,
.mutability = pointer.mutability,
.many = false,
.nullable = false,
});
const slice_builder = try unit.instructions.append(context.allocator, .{
.insert_value = .{
.expression = V{
@ -3776,7 +3792,12 @@ pub const Builder = struct {
},
},
.index = 0,
.new_value = expression_to_slice,
.new_value = .{
.value = .{
.runtime = pointer_gep,
},
.type = pointer_type,
},
},
});
try builder.appendInstruction(unit, context, slice_builder);
@ -4227,9 +4248,25 @@ pub const Builder = struct {
};
},
.array => |array| b: {
const loaded_array_like = switch (array_like_expression.value) {
.runtime => |instruction_index| switch (unit.instructions.get(instruction_index).*) {
.argument_declaration, .stack_slot => arg: {
const load = try unit.instructions.append(context.allocator, .{
.load = .{
.value = array_like_expression,
},
});
try builder.appendInstruction(unit, context, load);
break :arg load;
},
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
};
const gep = try unit.instructions.append(context.allocator, .{
.get_element_pointer = .{
.pointer = array_like_expression.value.runtime,
.pointer = loaded_array_like,
.base_type = array.type,
.index = index,
},
@ -4310,6 +4347,38 @@ pub const Builder = struct {
.type = gep_type,
};
},
.array => |array| b: {
switch (array_like_expression.value) {
.runtime => |instruction_index| switch (unit.instructions.get(instruction_index).*) {
.stack_slot => {},
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
}
const gep = try unit.instructions.append(context.allocator, .{
.get_element_pointer = .{
.pointer = array_like_expression.value.runtime,
.base_type = array.type,
.index = index,
},
});
const gep_type = try unit.getPointerType(context, .{
.type = array.type,
.termination = .none,
.mutability = .@"var",
.many = false,
.nullable = false,
});
break :b .{
.value = .{
.runtime = gep,
},
.type = gep_type,
};
},
else => |t| @panic(@tagName(t)),
};
@ -4342,6 +4411,7 @@ pub const Builder = struct {
break :b unit.types.get(gep.type).pointer.type;
},
.none => unit.types.get(gep.type).pointer.type,
else => |t| @panic(@tagName(t)),
},
};

View File

@ -2459,7 +2459,6 @@ pub const LLVM = struct {
}
fn emitLeftValue(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, v: Compilation.V) !*LLVM.Value {
_ = context; // autofix
switch (v.value) {
.runtime => |instruction_index| {
if (llvm.llvm_instruction_map.get(instruction_index)) |value| {
@ -2471,6 +2470,17 @@ pub const LLVM = struct {
const global_variable = llvm.global_variable_map.get(global_declaration).?;
return global_variable.toValue();
},
.get_element_pointer => |gep| {
const pointer = llvm.llvm_instruction_map.get(gep.pointer).?;
const index = try llvm.emitRightValue(unit, context, gep.index);
const indices = [1]*LLVM.Value{ index };
const base_type = try llvm.getType(unit, context, gep.base_type);
const in_bounds = true;
const get_element_pointer = llvm.builder.createGEP(base_type, pointer, &indices, indices.len, "gep", "gep".len, in_bounds) orelse unreachable;
try llvm.llvm_value_map.putNoClobber(context.allocator, v, get_element_pointer);
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, get_element_pointer);
return get_element_pointer;
},
else => |t| @panic(@tagName(t)),
}
}
@ -3091,6 +3101,15 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const global_variable = llvm.global_variable_map.get(global).?;
break :b global_variable.toValue();
},
.get_element_pointer => |gep| b: {
const index = try llvm.emitRightValue(unit, context, gep.index);
const pointer = llvm.llvm_instruction_map.get(gep.pointer).?;
const t = try llvm.getType(unit, context, gep.base_type);
const indices = [1]*LLVM.Value{index};
const in_bounds = true;
const get_element_pointer = llvm.builder.createGEP(t, pointer, &indices, indices.len, "gep", "gep".len, in_bounds) orelse unreachable;
break :b get_element_pointer;
},
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),

View File

@ -22,7 +22,7 @@ pub fn main() !void {
while (try standalone_iterator.next()) |entry| {
switch (entry.kind) {
.directory => try standalone_test_names.append(allocator, entry.name),
.directory => try standalone_test_names.append(allocator, try allocator.dupe(u8, entry.name)),
else => return error.junk_in_test_directory,
}
}
@ -38,6 +38,7 @@ pub fn main() !void {
const total_test_count = standalone_test_names.items.len;
for (standalone_test_names.items) |standalone_test_name| {
std.debug.assert(!std.mem.eql(u8, standalone_test_name, "else_ifrld"));
std.debug.print("{s}... ", .{standalone_test_name});
const source_file_path = try std.mem.concat(allocator, u8, &.{standalone_test_dir_path, "/", standalone_test_name, "/main.nat"});
const compile_run = try std.ChildProcess.run(.{

View File

@ -28,7 +28,9 @@ const format_usize = fn(n: usize, buffer: &[65]u8) []u8 {
while (true) {
const digit: u8 = #cast(absolute % 10);
index -= 1;
buffer[index] = '0' + digit;
const ch = '0' + digit;
buffer[index] = ch;
#assert(buffer[index] == ch);
absolute /= 10;
if (absolute == 0) {

View File

@ -0,0 +1,10 @@
const main = fn () s32 {
const ch = 'a';
var buffer: [1]u8 = undefined;
var ptr: &[1]u8 = buffer.&;
var index: usize = 0;
ptr[index] = ch;
const sub: u8 = ptr[index] - ch;
const result: u32 = sub;
return #cast(result);
}

View File

@ -0,0 +1,14 @@
const main = fn () s32 {
var buffer: [2]u8 = undefined;
const expected = 'a';
const index: usize = 1;
foo(buffer.&, index, expected);
const ch = buffer[index];
const sub = expected - ch;
const result: u32 = sub;
return #cast(result);
}
const foo = fn (buffer: &[2]u8, index: usize, ch: u8) void {
buffer[index] = ch;
}

View File

@ -0,0 +1,9 @@
const main = fn () s32 {
const ch = 'a';
var buffer: [1]u8 = undefined;
var index: usize = 0;
buffer[index] = ch;
const sub: u8 = buffer[index] - ch;
const result: u32 = sub;
return #cast(result);
}