From 3e9e4069f1487b67e09c9071e8b5b52ed4e6c8a3 Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Thu, 12 Jun 2025 20:47:12 -0600 Subject: [PATCH] Pass struct test --- src/compiler.bbb | 103 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 3 deletions(-) diff --git a/src/compiler.bbb b/src/compiler.bbb index 02832a1..69b8d27 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -6070,7 +6070,7 @@ parse = fn (module: &Module) void } >type_it = module.scope.types.first; - >forward_declaration: &Type = zero; + >type_forward_declaration: &Type = zero; while (type_it) { @@ -6078,7 +6078,7 @@ parse = fn (module: &Module) void { if (type_it.id == .forward_declaration) { - forward_declaration = type_it; + type_forward_declaration = type_it; break; } else @@ -6461,7 +6461,102 @@ parse = fn (module: &Module) void }, .struct => { - #trap(); + skip_space(module); + + >struct_type: &Type = undefined; + if (type_forward_declaration) + { + struct_type = type_forward_declaration; + } + else + { + struct_type = new_type(module, { + .id = .forward_declaration, + .name = global_name, + .scope = &module.scope, + zero, + }); + } + + if (consume_character_if_match(module, left_brace)) + { + >field_buffer: [256]Field = undefined; + + >byte_size: u64 = 0; + >byte_alignment: u32 = 1; + >field_count: u64 = 0; + + while (1) + { + skip_space(module); + + if (consume_character_if_match(module, right_brace)) + { + break; + } + + >field_index = field_count; + >field_line = get_line(module); + >field_name = parse_identifier(module); + + skip_space(module); + expect_character(module, ':'); + skip_space(module); + + >field_type = parse_type(module, scope); + + >field_byte_size = get_byte_size(field_type); + >field_byte_alignment = get_byte_alignment(field_type); + // Align struct size by field alignment + >field_byte_offset = align_forward(byte_size, #extend(field_byte_alignment)); + + field_buffer[field_index] = { + .name = field_name, + .type = field_type, + .offset = field_byte_offset, + .line = field_line, + }; + + byte_size = field_byte_offset + field_byte_size; + byte_alignment = #max(byte_alignment, field_byte_alignment); + + skip_space(module); + + consume_character_if_match(module, ','); + + field_count += 1; + } + + byte_size = align_forward(byte_size, #extend(byte_alignment)); + assert(byte_size % #extend(byte_alignment) == 0); + + skip_space(module); + consume_character_if_match(module, ';'); + + >fields = arena_allocate_slice[Field](module.arena, field_count); + memcpy(#pointer_cast(fields.pointer), #pointer_cast(&field_buffer), field_count * #byte_size(Field)); + + struct_type.content = { + .struct = { + .fields = fields, + .byte_size = byte_size, + .byte_alignment = byte_alignment, + .line = global_line, + .is_slice = 0, + .next = zero, + }, + }; + struct_type.id = .struct; + } + else + { + if (type_forward_declaration) + { + report_error(); + } + + expect_character(module, ';'); + } }, .typealias => { @@ -12469,6 +12564,8 @@ names: [_][]u8 = [ "bits_no_backing_type", "bits_return_u1", "bits_zero", + "comparison", + "global_struct", ]; [export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32