X Named member initialization
X Default values on structs so they don't have to be named
- [ ] #union on structs
+ [X] #union on structs
- [ ] #align on structs
+ [X] #align on structs
+
+ [X] #size on structs
[ ] 'use' enums and packages at an arbitrary scope
+ [ ] 'when' statements
+ - Compile time conditions
+ - Only evalutate code blocks that evaluate to be true
+
[ ] Array literals
[ ] Top level variable initialization
// Enum flags
Ast_Flag_Enum_Is_Flags = BH_BIT(11),
+
+ // Struct flags
+ Ast_Flag_Struct_Is_Union = BH_BIT(12),
} AstFlags;
typedef enum UnaryOp {
bh_arr(AstStructMember *) members;
+ u32 min_alignment, min_size;
+
// NOTE: Used to cache the actual type, since building
// a struct type is kind of complicated and should
// only happen once.
stupid_idea(1234)(1234) |> print();
varr : [5] Vec3;
- varr[2] = Vec3 .{4, 5, 6};
+ varr[2] = Vec3.{4, 5, 6};
mag_squared(varr[2]) |> print();
print(v2.y);
print(v2.z);
- buf := core.Buffer.{
- length = 16,
- };
+ buf := core.Buffer.{ length = 16 };
+
+ un : UnionTest;
+ un.f = 1.25f;
+ print_hex(cast(u64) un.i);
}
vadd :: proc (v1: Vec3, v2: Vec3) -> ^Vec3 {
out := cast(^Vec3) alloc(return_scratch_alloc, sizeof Vec3);
- out.x = v1.x + v2.x;
- out.y = v1.y + v2.y;
- out.z = v1.z + v2.z;
+ *out = Vec3.{
+ x = v1.x + v2.x,
+ y = v1.y + v2.y,
+ z = v1.z + v2.z,
+ };
return out;
+}
+
+UnionTest :: struct #union {
+ i : i32;
+ f : f32;
}
\ No newline at end of file
bh_arr_new(global_heap_allocator, s_node->members, 4);
+ while (parser->curr->type == '#') {
+ if (parser->hit_unexpected_token) return NULL;
+
+ if (parse_possible_directive(parser, "union")) {
+ s_node->flags |= Ast_Flag_Struct_Is_Union;
+ }
+
+ else if (parse_possible_directive(parser, "align")) {
+ AstNumLit* numlit = parse_int_literal(parser);
+ if (numlit == NULL) return NULL;
+
+ s_node->min_alignment = numlit->value.i;
+ }
+
+ else if (parse_possible_directive(parser, "size")) {
+ AstNumLit* numlit = parse_int_literal(parser);
+ if (numlit == NULL) return NULL;
+
+ s_node->min_size = numlit->value.i;
+ }
+
+ else {
+ OnyxToken* directive_token = expect_token(parser, '#');
+ OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
+
+ onyx_message_add(Msg_Type_Unknown_Directive,
+ directive_token->pos,
+ symbol_token->text, symbol_token->length);
+ }
+ }
+
expect_token(parser, '{');
while (parser->curr->type != '}') {
if (parser->hit_unexpected_token) return s_node;
bh_table_init(global_heap_allocator, s_type->Struct.members, s_type->Struct.mem_count);
bh_arr_new(global_heap_allocator, s_type->Struct.memarr, s_type->Struct.mem_count);
+ b32 is_union = (s_node->flags & Ast_Flag_Struct_Is_Union) != 0;
+ u32 size = 0;
u32 offset = 0;
u32 alignment = 1, mem_alignment;
u32 idx = 0;
bh_table_put(StructMember, s_type->Struct.members, (*member)->token->text, smem);
token_toggle_end((*member)->token);
- offset += type_size_of((*member)->type);
+ u32 type_size = type_size_of((*member)->type);
+ if (!is_union) offset += type_size;
+ if (!is_union) size += type_size;
+ else size = bh_max(size, type_size);
+
idx++;
}
token_toggle_end((*member)->token);
}
+ alignment = bh_max(s_node->min_alignment, alignment);
s_type->Struct.aligment = alignment;
- if (offset % alignment != 0) {
- offset += alignment - (offset % alignment);
+ if (size % alignment != 0) {
+ size += alignment - (size % alignment);
}
- s_type->Struct.size = offset;
+
+ size = bh_max(s_node->min_size, size);
+ s_type->Struct.size = size;
return s_type;
}