mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Fix subtype polymorphism
This commit is contained in:
+2
-2
@@ -33,8 +33,8 @@ main :: proc() {
|
|||||||
print_f32(f.jump_height); nl()
|
print_f32(f.jump_height); nl()
|
||||||
print_f32(parent.jump_height); nl()
|
print_f32(parent.jump_height); nl()
|
||||||
|
|
||||||
print_name(f.entity, Vec3{1, 2, 3})
|
print_name(f, Vec3{1, 2, 3})
|
||||||
print_name(parent.entity, Vec3{3, 2, 1})
|
print_name(parent, Vec3{3, 2, 1})
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ void update_expr_type (Checker *c, AstNode *e, Type *type, b32 fina
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
b32 check_is_assignable_to_using_subtype(Checker *c, Type *dst, Type *src) {
|
b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||||
Type *prev_src = src;
|
Type *prev_src = src;
|
||||||
// Type *prev_dst = dst;
|
// Type *prev_dst = dst;
|
||||||
src = get_base_type(type_deref(src));
|
src = get_base_type(type_deref(src));
|
||||||
@@ -35,6 +35,10 @@ b32 check_is_assignable_to_using_subtype(Checker *c, Type *dst, Type *src) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b32 ok = check_is_assignable_to_using_subtype(dst, f->type);
|
||||||
|
if (ok) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +95,7 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
|
|||||||
|
|
||||||
if (is_argument) {
|
if (is_argument) {
|
||||||
// NOTE(bill): Polymorphism for subtyping
|
// NOTE(bill): Polymorphism for subtyping
|
||||||
if (check_is_assignable_to_using_subtype(c, type, src)) {
|
if (check_is_assignable_to_using_subtype(type, src)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-12
@@ -1288,7 +1288,34 @@ ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
|
||||||
|
Type *prev_src = src;
|
||||||
|
// Type *prev_dst = dst;
|
||||||
|
src = get_base_type(type_deref(src));
|
||||||
|
// dst = get_base_type(type_deref(dst));
|
||||||
|
b32 src_is_ptr = src != prev_src;
|
||||||
|
// b32 dst_is_ptr = dst != prev_dst;
|
||||||
|
|
||||||
|
GB_ASSERT(src->kind == Type_Struct);
|
||||||
|
for (isize i = 0; i < src->Struct.field_count; i++) {
|
||||||
|
Entity *f = src->Struct.fields[i];
|
||||||
|
if (f->kind == Entity_Variable && f->Variable.anonymous) {
|
||||||
|
if (are_types_identical(dst, f->type)) {
|
||||||
|
return f->token.string;
|
||||||
|
}
|
||||||
|
if (src_is_ptr && is_type_pointer(dst)) {
|
||||||
|
if (are_types_identical(type_deref(dst), f->type)) {
|
||||||
|
return f->token.string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String name = lookup_polymorphic_field(info, dst, f->type);
|
||||||
|
if (name.len > 0) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make_string("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_argument) {
|
ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_argument) {
|
||||||
@@ -1394,18 +1421,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
|
|||||||
Type *sb = get_base_type(type_deref(src));
|
Type *sb = get_base_type(type_deref(src));
|
||||||
b32 src_is_ptr = src != sb;
|
b32 src_is_ptr = src != sb;
|
||||||
if (sb->kind == Type_Struct) {
|
if (sb->kind == Type_Struct) {
|
||||||
// NOTE(bill): Check
|
String field_name = lookup_polymorphic_field(proc->module->info, t, src);
|
||||||
String field_name = {};
|
// gb_printf("field_name: %.*s\n", LIT(field_name));
|
||||||
for (isize i = 0; i < sb->Struct.field_count; i++) {
|
|
||||||
Entity *f = sb->Struct.fields[i];
|
|
||||||
if (f->kind == Entity_Variable && f->Variable.anonymous) {
|
|
||||||
if (are_types_identical(t, f->type)) {
|
|
||||||
field_name = f->token.string;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field_name.len > 0) {
|
if (field_name.len > 0) {
|
||||||
// NOTE(bill): It can be casted
|
// NOTE(bill): It can be casted
|
||||||
Selection sel = lookup_field(sb, field_name, false);
|
Selection sel = lookup_field(sb, field_name, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user