added: `#distinct` types over any type
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 8 May 2023 15:41:13 +0000 (10:41 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 8 May 2023 15:41:13 +0000 (10:41 -0500)
CHANGELOG
compiler/src/astnodes.c
compiler/src/types.c
compiler/src/wasm_emit.c

index c796711ee12a4103e2a459496037224b3eabc944..4dc2c74997689e2a2c6c22f7d0bfd0f9a398ceb7 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,8 @@ Release XXX
 Additions:
 * Ability to have tags on `#foreign` block procedures.
     - This will enable the creation different binding generators, such jsbindgen.
+* `#distinct` types can now be made over any type.
+    - Used to be only primitives.
 * New `logo-new-256.ico` for favicon on website.
 
 Removals:
index 8ad492251b55e4d28e9a96ddd8ad5210b4e9b192..5b687cb04b57b10f4215f7ea9e7972d43d4ae218 100644 (file)
@@ -1210,6 +1210,34 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) {
 
     if (from_->id == to_->id) return 1;
 
+    if (to->kind == Type_Kind_Distinct) {
+        if (types_are_compatible(to->Distinct.base_type, from)) {
+            return 1;
+        }
+
+        if (from->kind == Type_Kind_Distinct && types_are_compatible(to, from->Distinct.base_type)) {
+            return 1;
+        }
+
+        *err_msg = "Cannot convert from a distinct type to the wrong destination type.";
+        return 0;
+    }
+
+    if (from->kind == Type_Kind_Distinct) {
+        if (types_are_compatible(from->Distinct.base_type, to)) {
+            return 1;
+        }
+
+        if (to->kind == Type_Kind_Distinct && types_are_compatible(from, to->Distinct.base_type)) {
+            return 1;
+        }
+
+        *err_msg = "Cannot convert to a distinct type from the wrong destination type.";
+        return 0;
+    }
+
+
+
     if (from->kind == Type_Kind_Enum) from = from->Enum.backing;
     if (to->kind == Type_Kind_Enum) to = to->Enum.backing;
 
@@ -1248,26 +1276,6 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) {
         }
     }
 
-    if (to->kind == Type_Kind_Distinct) {
-        if (!types_are_compatible(to->Distinct.base_type, from)) {
-            // :BadErrorMessage
-            *err_msg = "Cannot convert to a distinct type using the wrong base type.";
-            return 0;
-        } else {
-            return 1;
-        }
-    }
-
-    if (from->kind == Type_Kind_Distinct) {
-        if (!types_are_compatible(from->Distinct.base_type, to)) {
-            // :BadErrorMessage
-            *err_msg = "Cannot convert from a distinct type to the wrong destination type.";
-            return 0;
-        } else {
-            return 1;
-        }
-    }
-
     if (from->kind == Type_Kind_Slice || to->kind == Type_Kind_Slice) {
         if ((from->kind != Type_Kind_Slice || to->kind != Type_Kind_Slice)
             || to->Slice.elem->kind != Type_Kind_Pointer || from->Slice.elem->kind != Type_Kind_Pointer
index 8445b905f03aca3c6093950990ab223ffd86e744..d4d85334b330bcf009cb39d06cbc9aa8e81bc4e1 100644 (file)
@@ -664,10 +664,10 @@ static Type* type_build_from_ast_inner(bh_allocator alloc, AstType* type_node, b
 
             Type *base_type = type_build_from_ast(alloc, distinct->base_type);
             if (base_type == NULL) return NULL;
-            if (base_type->kind != Type_Kind_Basic && base_type->kind != Type_Kind_Pointer) {
-                onyx_report_error(distinct->token->pos, Error_Critical, "Distinct types can only be made out of primitive types. '%s' is not a primitive type.", type_get_name(base_type));
-                return NULL;
-            }
+            // if (base_type->kind != Type_Kind_Basic && base_type->kind != Type_Kind_Pointer) {
+            //     onyx_report_error(distinct->token->pos, Error_Critical, "Distinct types can only be made out of primitive types. '%s' is not a primitive type.", type_get_name(base_type));
+            //     return NULL;
+            // }
 
             Type *distinct_type = type_create(Type_Kind_Distinct, alloc, 0);
             distinct_type->Distinct.base_type = base_type;
index 7ae39df01117d3e09127f0259217c0368cc766b7..14102044a87f895617b65738ba829e0fb3821795 100644 (file)
 #define WASM_TYPE_VOID    0x00
 
 static b32 onyx_type_is_stored_in_memory(Type *type) {
+    if (type->kind == Type_Kind_Distinct) {
+        type = type->Distinct.base_type;
+    }
+
     if (type_struct_is_just_one_basic_value(type)) return 0;
 
     return type->kind == Type_Kind_Struct
@@ -965,10 +969,11 @@ EMIT_FUNC(store_instruction, Type* type, u32 offset) {
         return;
     }
 
+    if (type->kind == Type_Kind_Function) assert(5678 && 0);
     if (type->kind == Type_Kind_Struct)   type = type_struct_is_just_one_basic_value(type);
     if (type->kind == Type_Kind_Enum)     type = type->Enum.backing;
-    if (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
-    if (type->kind == Type_Kind_Function) assert(5678 && 0);
+
+    while (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
 
     assert(type);
 
@@ -1079,9 +1084,10 @@ EMIT_FUNC(load_instruction, Type* type, u32 offset) {
 
     if (type->kind == Type_Kind_Struct)   type = type_struct_is_just_one_basic_value(type);
     if (type->kind == Type_Kind_Enum)     type = type->Enum.backing;
-    if (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
     if (type->kind == Type_Kind_Function) assert(1234 && 0);
 
+    while (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
+
     assert(type);
 
     i32 load_size   = type_size_of(type);