For each integer

This commit is contained in:
David Gonzalez Martin 2025-04-25 13:26:38 -06:00
parent 1983d50280
commit 7bd3a5e3a4
3 changed files with 242 additions and 158 deletions

View File

@ -511,7 +511,7 @@ pub const Type = struct {
pub const Pointer = struct { pub const Pointer = struct {
type: *Type, type: *Type,
alignment: u32, alignment: ?u32,
}; };
pub const Function = struct { pub const Function = struct {
@ -630,6 +630,7 @@ pub const Type = struct {
.structure => |structure| structure.byte_alignment, .structure => |structure| structure.byte_alignment,
.bits => |bits| bits.backing_type.get_byte_alignment(), .bits => |bits| bits.backing_type.get_byte_alignment(),
.alias => |alias| alias.type.get_byte_alignment(), .alias => |alias| alias.type.get_byte_alignment(),
.unresolved => unreachable,
else => @trap(), else => @trap(),
}; };
return result; return result;
@ -734,7 +735,13 @@ pub const Statement = struct {
left_values: []const Value.Kind, left_values: []const Value.Kind,
right_values: []const *Value, right_values: []const *Value,
predicate: *Statement, predicate: *Statement,
kind: Kind,
scope: Scope, scope: Scope,
const Kind = enum {
slice,
range,
};
}; };
const Assignment = struct { const Assignment = struct {
@ -913,6 +920,7 @@ pub const Value = struct {
}; };
const Intrinsic = union(Id) { const Intrinsic = union(Id) {
alignof: *Type,
byte_size: *Type, byte_size: *Type,
enum_name: *Value, enum_name: *Value,
extend: *Value, extend: *Value,
@ -930,6 +938,7 @@ pub const Value = struct {
va_arg: VaArg, va_arg: VaArg,
const Id = enum { const Id = enum {
alignof,
byte_size, byte_size,
enum_name, enum_name,
extend, extend,
@ -1491,7 +1500,7 @@ pub const Module = struct {
pub fn get_pointer_type(module: *Module, pointer: Pointer) *Type { pub fn get_pointer_type(module: *Module, pointer: Pointer) *Type {
const p = Type.Pointer{ const p = Type.Pointer{
.type = pointer.type, .type = pointer.type,
.alignment = if (pointer.alignment) |a| a else pointer.type.get_byte_alignment(), .alignment = if (pointer.alignment) |a| a else if (pointer.type.bb != .unresolved) pointer.type.get_byte_alignment() else null,
}; };
const all_types = module.types.get_slice(); const all_types = module.types.get_slice();
const pointer_type = for (module.pointer_types.get_slice()) |pointer_type_index| { const pointer_type = for (module.pointer_types.get_slice()) |pointer_type_index| {
@ -2615,6 +2624,7 @@ pub const Module = struct {
.kind = .for_each, .kind = .for_each,
.parent = scope, .parent = scope,
}, },
.kind = undefined,
}, },
}, },
}; };
@ -2671,26 +2681,60 @@ pub const Module = struct {
var right_value_buffer: [64]*Value = undefined; var right_value_buffer: [64]*Value = undefined;
var right_value_count: u64 = 0; var right_value_count: u64 = 0;
while (true) {
module.skip_space();
const identifier = module.parse_value(scope, .{ right_value_buffer[right_value_count] = module.parse_value(scope, .{
.kind = .left, .kind = .left,
}); });
right_value_buffer[right_value_count] = identifier;
right_value_count += 1; right_value_count += 1;
module.skip_space(); module.skip_space();
if (!module.consume_character_if_match(',')) { const token = module.tokenize();
const kind: Statement.ForEach.Kind = switch (token) {
.@")" => b: {
module.offset += 1;
break :b .slice;
},
.@".." => b: {
if (left_value_count != 1) {
module.report_error();
}
right_value_buffer[0].kind = .right;
right_value_buffer[right_value_count] = module.parse_value(scope, .{
.kind = .right,
});
right_value_count += 1;
module.expect_character(right_parenthesis); module.expect_character(right_parenthesis);
break; break :b .range;
} },
} else => @trap(),
};
statement.bb.for_each.kind = kind;
module.skip_space(); module.skip_space();
// if (!module.consume_character_if_match(',')) {
// module.expect_character(right_parenthesis);
// @trap();
// }
//
// while (true) {
// module.skip_space();
//
// right_value_buffer[right_value_count] = module.parse_value(scope, .{
// .kind = .left,
// });
// right_value_count += 1;
//
// module.skip_space();
//
// if (!module.consume_character_if_match(',')) {
// module.expect_character(right_parenthesis);
// break;
// }
// }
if (left_value_count != right_value_count) { if (kind == .slice and left_value_count != right_value_count) {
module.report_error(); module.report_error();
} }
@ -3122,6 +3166,20 @@ pub const Module = struct {
const value = module.values.add(); const value = module.values.add();
value.* = switch (intrinsic) { value.* = switch (intrinsic) {
.alignof => blk: {
module.skip_space();
module.expect_character(left_parenthesis);
module.skip_space();
const ty = module.parse_type();
module.expect_character(right_parenthesis);
break :blk .{
.bb = .{
.intrinsic = .{
.alignof = ty,
},
},
};
},
.byte_size => blk: { .byte_size => blk: {
module.skip_space(); module.skip_space();
module.expect_character(left_parenthesis); module.expect_character(left_parenthesis);
@ -4715,7 +4773,7 @@ pub const Module = struct {
.scalar => module.create_load(.{ .type = va_arg.type, .value = llvm_address }), .scalar => module.create_load(.{ .type = va_arg.type, .value = llvm_address }),
.aggregate => if (left_llvm) |l| b: { .aggregate => if (left_llvm) |l| b: {
uint64.resolve(module); uint64.resolve(module);
_ = module.llvm.builder.create_memcpy(l, left_type.?.bb.pointer.alignment, llvm_address, va_arg.type.get_byte_alignment(), uint64.llvm.abi.?.to_integer().get_constant(va_arg.type.get_byte_size(), 0).to_value()); _ = module.llvm.builder.create_memcpy(l, left_type.?.bb.pointer.alignment.?, llvm_address, va_arg.type.get_byte_alignment(), uint64.llvm.abi.?.to_integer().get_constant(va_arg.type.get_byte_size(), 0).to_value());
break :b l; break :b l;
} else llvm_address, } else llvm_address,
.complex => @trap(), .complex => @trap(),
@ -8219,6 +8277,8 @@ pub const Module = struct {
for_loop.scope.llvm = lexical_block.to_scope(); for_loop.scope.llvm = lexical_block.to_scope();
} }
switch (for_loop.kind) {
.slice => {
const index_type = module.integer_type(64, false); const index_type = module.integer_type(64, false);
index_type.resolve(module); index_type.resolve(module);
const index_zero = index_type.llvm.abi.?.get_zero().to_value(); const index_zero = index_type.llvm.abi.?.get_zero().to_value();
@ -8355,6 +8415,14 @@ pub const Module = struct {
module.llvm.builder.position_at_end(loop_exit_block); module.llvm.builder.position_at_end(loop_exit_block);
}, },
.range => {
assert(for_loop.locals.len == 1);
assert(for_loop.left_values.len == 1);
assert(for_loop.right_values.len == 2);
@trap();
},
}
},
} }
} }
@ -8408,7 +8476,7 @@ pub const Module = struct {
global_variable.to_value().set_alignment(alignment); global_variable.to_value().set_alignment(alignment);
const uint64 = module.integer_type(64, false); const uint64 = module.integer_type(64, false);
uint64.resolve(module); uint64.resolve(module);
_ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment, global_variable.to_value(), alignment, uint64.llvm.abi.?.to_integer().get_constant(array_initialization.values.len * pointer_type.bb.pointer.type.bb.array.element_type.get_byte_size(), @intFromBool(false)).to_value()); _ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment.?, global_variable.to_value(), alignment, uint64.llvm.abi.?.to_integer().get_constant(array_initialization.values.len * pointer_type.bb.pointer.type.bb.array.element_type.get_byte_size(), @intFromBool(false)).to_value());
}, },
false => @trap(), false => @trap(),
}, },
@ -8426,7 +8494,7 @@ pub const Module = struct {
global_variable.to_value().set_alignment(alignment); global_variable.to_value().set_alignment(alignment);
const uint64 = module.integer_type(64, false); const uint64 = module.integer_type(64, false);
uint64.resolve(module); uint64.resolve(module);
_ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment, global_variable.to_value(), alignment, uint64.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), @intFromBool(false)).to_value()); _ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment.?, global_variable.to_value(), alignment, uint64.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), @intFromBool(false)).to_value());
}, },
false => { false => {
var max_field_index: u64 = 0; var max_field_index: u64 = 0;
@ -8469,7 +8537,7 @@ pub const Module = struct {
uint8.resolve(module); uint8.resolve(module);
const uint64 = module.integer_type(64, false); const uint64 = module.integer_type(64, false);
uint64.resolve(module); uint64.resolve(module);
_ = module.llvm.builder.create_memset(destination_pointer, uint8.llvm.abi.?.get_zero().to_value(), uint64.llvm.abi.?.to_integer().get_constant(memset_size, 0).to_value(), pointer_type.bb.pointer.alignment); _ = module.llvm.builder.create_memset(destination_pointer, uint8.llvm.abi.?.get_zero().to_value(), uint64.llvm.abi.?.to_integer().get_constant(memset_size, 0).to_value(), pointer_type.bb.pointer.alignment.?);
} }
}, },
}, },
@ -8614,13 +8682,13 @@ pub const Module = struct {
u8_type.resolve(module); u8_type.resolve(module);
const u64_type = module.integer_type(64, false); const u64_type = module.integer_type(64, false);
u64_type.resolve(module); u64_type.resolve(module);
_ = module.llvm.builder.create_memset(left_llvm, u8_type.llvm.abi.?.get_zero().to_value(), u64_type.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), 0).to_value(), pointer_type.bb.pointer.alignment); _ = module.llvm.builder.create_memset(left_llvm, u8_type.llvm.abi.?.get_zero().to_value(), u64_type.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), 0).to_value(), pointer_type.bb.pointer.alignment.?);
}, },
.variable_reference => |variable| switch (right.kind) { .variable_reference => |variable| switch (right.kind) {
.left => @trap(), .left => @trap(),
.right => { .right => {
const uint64 = module.integer_type(64, false); const uint64 = module.integer_type(64, false);
_ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment, variable.storage.?.llvm.?, variable.storage.?.type.?.bb.pointer.alignment, uint64.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), @intFromBool(false)).to_value()); _ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment.?, variable.storage.?.llvm.?, variable.storage.?.type.?.bb.pointer.alignment.?, uint64.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), @intFromBool(false)).to_value());
}, },
}, },
.field_access => |field_access| { .field_access => |field_access| {
@ -8634,7 +8702,7 @@ pub const Module = struct {
module.emit_value(field_access.aggregate, .memory); module.emit_value(field_access.aggregate, .memory);
const gep = module.llvm.builder.create_struct_gep(struct_type.llvm.abi.?.to_struct(), field_access.aggregate.llvm.?, field_index); const gep = module.llvm.builder.create_struct_gep(struct_type.llvm.abi.?.to_struct(), field_access.aggregate.llvm.?, field_index);
const uint64 = module.integer_type(64, false); const uint64 = module.integer_type(64, false);
_ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment, gep, value_type.get_byte_alignment(), uint64.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), @intFromBool(false)).to_value()); _ = module.llvm.builder.create_memcpy(left_llvm, pointer_type.bb.pointer.alignment.?, gep, value_type.get_byte_alignment(), uint64.llvm.abi.?.to_integer().get_constant(value_type.get_byte_size(), @intFromBool(false)).to_value());
}, },
.undefined => {}, .undefined => {},
else => @trap(), else => @trap(),

View File

@ -443,6 +443,11 @@ arena_allocate_bytes = fn (arena: &Arena, size: u64, alignment: u64) &u8
return result; return result;
} }
arena_allocate = macro [T] (arena: &Arena, count: u64) &T
{
return arena_allocate_bytes(arena, #byte_size(T) * count, #alignof(T));
}
arena_duplicate_string = fn (arena: &Arena, string: []u8) []u8 arena_duplicate_string = fn (arena: &Arena, string: []u8) []u8
{ {
>result = arena_allocate_bytes(arena, string.length + 1, 1); >result = arena_allocate_bytes(arena, string.length + 1, 1);
@ -583,6 +588,7 @@ CompileOptions = struct
compile = fn (arena: &Arena, options: CompileOptions) void compile = fn (arena: &Arena, options: CompileOptions) void
{ {
>signs: [2]u1 = [0, 1];
} }
compile_file = fn (arena: &Arena, compile_options: CompileFile) void compile_file = fn (arena: &Arena, compile_options: CompileFile) void

10
tests/for_each_int.bbb Normal file
View File

@ -0,0 +1,10 @@
[export] main = fn [cc(c)] () s32
{
>top: s32 = 64;
>accummulator: s32 = 0;
for (i: 0..top)
{
accummulator += 1;
}
return accummulator - top;
}