else do io.write_str(writer, "<anonymous struct>");
}
+ case .Polymorphic_Struct {
+ s := cast(^Type_Info_Polymorphic_Struct) info;
+ if s.name.count > 0 do io.write_str(writer, s.name);
+ else do io.write_str(writer, "<anonymous polymorphic struct>");
+ }
+
case .Compound {
comp := cast(^Type_Info_Compound) info;
io.write_str(writer, "(");
return 0;
}
+struct_constructed_from :: (struct_type: type_expr, base_type: type_expr) -> bool {
+ struct_info := get_type_info(struct_type);
+ if struct_info.kind != .Struct do return false;
+
+ return (cast(^Type_Info_Struct) struct_info).constructed_from == base_type;
+}
+
#operator == (t1: Type_Info_Function, t2: Type_Info_Function) -> bool {
if t1.parameter_types.count != t2.parameter_types.count do return false;
if t1.return_type != t2.return_type do return false;
Type_Info :: struct {
// This must match the order of the elements in onyxtypes.h
Kind :: enum {
- Invalid :: 0x00; // Unused
- Basic :: 0x01;
- Pointer :: 0x02;
- Function :: 0x03;
- Struct :: 0x04;
- Compound :: 0x05;
- Array :: 0x06;
- Slice :: 0x07;
- Dynamic_Array :: 0x08;
- Variadic_Argument :: 0x09;
- Enum :: 0x0a;
+ Invalid :: 0x00; // Unused
+ Basic :: 0x01;
+ Pointer :: 0x02;
+ Function :: 0x03;
+ Struct :: 0x04;
+ Polymorphic_Struct :: 0x05;
+ Compound :: 0x06;
+ Array :: 0x07;
+ Slice :: 0x08;
+ Dynamic_Array :: 0x09;
+ Variadic_Argument :: 0x0a;
+ Enum :: 0x0b;
}
kind := Kind.Invalid;
tags: [] any;
}
+ constructed_from: type_expr;
name: str;
members: [] Member;
parameters: [] any;
tags: [] any;
}
+Type_Info_Polymorphic_Struct :: struct {
+ use base : Type_Info;
+
+ name: str;
+ tags: [] any;
+}
+
Type_Info_Compound :: struct {
use base : Type_Info;
struct AstType *constructed_from; \
bh_arr(struct AstTyped *) meta_tags; \
}) \
+ TYPE_KIND(PolyStruct, struct { \
+ char* name; \
+ bh_arr(struct AstTyped *) meta_tags; \
+ }) \
TYPE_KIND(Compound, struct { \
u32 count; \
u32 size; \
SHIFT :: 0x08;
}
- get_name :: (use e: ^KeyboardEvent) -> str do return str.{ ~~keyname, ~~keyname_count };
+ get_name :: (use e: ^KeyboardEvent) => str.{ ~~keyname, ~~keyname_count };
}
MouseEvent :: struct {
if (type_build_from_ast(context.ast_alloc, (AstType*) expr) == NULL) {
YIELD(expr->token->pos, "Trying to construct type.");
}
+ } else {
+ type_build_from_ast(context.ast_alloc, (AstType*) expr);
}
expr->type = &basic_types[Basic_Kind_Type_Index];
bh_arr_push(ds->members, (AstStructMember *) ast_clone(a, *smem));
}
+ ds->meta_tags = NULL;
+ bh_arr_new(global_heap_allocator, ds->meta_tags, bh_arr_length(ss->meta_tags));
+ bh_arr_each(AstTyped *, tag, ss->meta_tags) {
+ bh_arr_push(ds->meta_tags, (AstTyped *) ast_clone(a, *tag));
+ }
+
ds->stcache = NULL;
break;
}
- case Ast_Kind_Struct_Member:
+ case Ast_Kind_Struct_Member: {
C(AstStructMember, type_node);
C(AstStructMember, initial_value);
+
+ AstStructMember *ds = (AstStructMember *) nn;
+ AstStructMember *ss = (AstStructMember *) node;
+
+ ds->meta_tags = NULL;
+ bh_arr_new(global_heap_allocator, ds->meta_tags, bh_arr_length(ss->meta_tags));
+ bh_arr_each(AstTyped *, tag, ss->meta_tags) {
+ bh_arr_push(ds->meta_tags, (AstTyped *) ast_clone(a, *tag));
+ }
+
break;
+ }
case Ast_Kind_Poly_Call_Type: {
AstPolyCallType* pcd = (AstPolyCallType *) nn;
case Ast_Kind_Type_Raw_Alias:
return ((AstTypeRawAlias *) type_node)->to;
- case Ast_Kind_Poly_Struct_Type:
+ case Ast_Kind_Poly_Struct_Type: {
//onyx_report_error(type_node->token->pos,
// "This structure is polymorphic, which means you need to provide arguments to it to make it a concrete structure. "
// "This error message is probably in the wrong place, so look through your code for uses of this struct.");
+
+ if (type_node->type_id != 0) return NULL;
+
+ Type* p_type = type_create(Type_Kind_PolyStruct, alloc, 0);
+ p_type->ast_type = type_node;
+ p_type->PolyStruct.name = ((AstPolyStructType *) type_node)->name;
+ p_type->PolyStruct.meta_tags = ((AstPolyStructType *) type_node)->base_struct->meta_tags;
+
+ type_register(p_type);
return NULL;
- break;
+ }
case Ast_Kind_Poly_Call_Type: {
AstPolyCallType* pc_type = (AstPolyCallType *) type_node;
bh_buffer_write_u32(&table_buffer, type->kind);
bh_buffer_write_u32(&table_buffer, type_size_of(type));
bh_buffer_write_u32(&table_buffer, type_alignment_of(type));
- bh_buffer_write_u32(&table_buffer, 0);
+
+ if (type->Struct.constructed_from != NULL) {
+ bh_buffer_write_u32(&table_buffer, type->Struct.constructed_from->type_id);
+ } else {
+ bh_buffer_write_u32(&table_buffer, 0);
+ }
+
PATCH;
bh_buffer_write_u64(&table_buffer, name_base);
bh_buffer_write_u64(&table_buffer, name_length);
break;
}
+
+ case Type_Kind_PolyStruct: {
+ u32* tag_locations = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(type->PolyStruct.meta_tags));
+ memset(tag_locations, 0, sizeof(u32) * bh_arr_length(type->PolyStruct.meta_tags));
+
+ u32 name_base = table_buffer.length;
+ u32 name_length = strlen(type->PolyStruct.name);
+ bh_buffer_append(&table_buffer, type->PolyStruct.name, name_length);
+
+ i32 i = 0;
+ bh_arr_each(AstTyped *, tag, type->PolyStruct.meta_tags) {
+ AstTyped* value = *tag;
+ assert(value->flags & Ast_Flag_Comptime);
+ assert(value->type);
+
+ u32 size = type_size_of(value->type);
+ bh_buffer_align(&table_buffer, type_alignment_of(value->type));
+ tag_locations[i] = table_buffer.length;
+
+ bh_buffer_grow(&table_buffer, table_buffer.length + size);
+ u8* buffer = table_buffer.data + table_buffer.length;
+
+ assert(emit_raw_data_(module, buffer, value));
+ table_buffer.length += size;
+
+ i += 1;
+ }
+
+ bh_buffer_align(&table_buffer, 8);
+ u32 tags_base = table_buffer.length;
+ u32 tags_count = bh_arr_length(type->PolyStruct.meta_tags);
+
+ fori (i, 0, tags_count) {
+ PATCH;
+ bh_buffer_write_u64(&table_buffer, tag_locations[i]);
+ bh_buffer_write_u64(&table_buffer, type->PolyStruct.meta_tags[i]->type->id);
+ }
+
+ bh_buffer_align(&table_buffer, 8);
+ table_info[type_idx] = table_buffer.length;
+ bh_buffer_write_u32(&table_buffer, type->kind);
+ bh_buffer_write_u32(&table_buffer, 0);
+ bh_buffer_write_u32(&table_buffer, 0);
+ bh_buffer_write_u32(&table_buffer, 0);
+ PATCH;
+ bh_buffer_write_u64(&table_buffer, name_base);
+ bh_buffer_write_u64(&table_buffer, name_length);
+ PATCH;
+ bh_buffer_write_u64(&table_buffer, tags_base);
+ bh_buffer_write_u64(&table_buffer, tags_count);
+
+ break;
+ }
}
}