added 'unique' names for structs and enums
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 18 Dec 2020 16:11:38 +0000 (10:11 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 18 Dec 2020 16:11:38 +0000 (10:11 -0600)
docs/todo
include/onyxtypes.h
misc/onyx.sublime-build
onyx
src/onyxtypes.c
src/onyxutils.c

index 310ccc5375e8990853edbe2ef8bc0c49218d329e..f761d8651717d472f20296730f406f7cfac0e399 100644 (file)
--- a/docs/todo
+++ b/docs/todo
@@ -79,6 +79,22 @@ Language Cohesion:
         easier to talk about types in a concrete way (for polymorphism and such),
         and would prepare the compiler to output type information into data section.
 
+    [ ] Switches should have range based statements, i.e.
+            switch expr {
+                case 10 .. 14 do ...
+            }
+
+        The only reason I have not implemented this feature is because it would
+        introduce a slight inconsistency in the language design. Generally, the
+        range (..) operator talks about ranges as inclusive low and exclusive
+        high, which makes sense for for-loops and the like. However, for the switch
+        statement, I think that would be very confusing. In the example above,
+        I would expect the case to trip when `expr` is 14. This isn't a techinal
+        problem; implementing this feature will be fairly straight forward. It
+        is just a language design problems, because it requires a bit of extra
+        thought to remember that ranges in for-loops and slices are NOT inclusive
+        on the upper end.
+
 API Expansion:
     There are many different places where the standard API for WASI and JS
     backends could be improved. Here are some of the target areas.
index 7dbe2a4cf454e3cda974ca35f9143032e0381a42..15bf08566e50368257754c9545fd6e26d67ca3f1 100644 (file)
@@ -79,6 +79,7 @@ typedef struct StructMember {
         Type* params[];                                           \
     })                                                            \
     TYPE_KIND(Struct, struct {                                    \
+        u64 unique_id;                                            \
         char* name;                                               \
         u32 size;                                                 \
         u16 alignment, mem_count;                                 \
@@ -90,7 +91,11 @@ typedef struct StructMember {
     TYPE_KIND(Slice, struct { Type *ptr_to_data; })               \
     TYPE_KIND(DynArray, struct { Type *ptr_to_data; })            \
     TYPE_KIND(VarArgs, struct { Type *ptr_to_data; })             \
-    TYPE_KIND(Enum, struct { char* name; Type* backing; })
+    TYPE_KIND(Enum, struct {                                      \
+        u64 unique_id;                                            \
+        char* name;                                               \
+        Type* backing;                                            \
+    })
 
 typedef enum TypeKind {
     Type_Kind_Invalid,
@@ -140,6 +145,7 @@ Type* type_make_slice(bh_allocator alloc, Type* of);
 Type* type_make_dynarray(bh_allocator alloc, Type* of);
 Type* type_make_varargs(bh_allocator alloc, Type* of);
 
+const char* type_get_unique_name(Type* type);
 const char* type_get_name(Type* type);
 u32 type_get_alignment_log2(Type* type);
 
index fcf81eacf1dd8a77fb7fd93f225adf8390d496bb..333000a3177f22d2dbb5c70830c11fe67d7e7c6b 100644 (file)
@@ -1,6 +1,6 @@
 {
        "target": "exec",
-       "shell_cmd": "/usr/bin/onyx -o \"${folder}/${file_base_name}.wasm\" \"$file\"",
+       "shell_cmd": "/usr/bin/onyx -V -o \"${folder}/${file_base_name}.wasm\" \"$file\"",
        "working_dir": "${folder}",
        "selector": "source.onyx",
        "file_regex": "^\\(([^:]+):([0-9]+),([0-9]+)\\) (.*)",
diff --git a/onyx b/onyx
index 94eaf2bc5177bb50869e37e48c495bf12f844b5b..c499787463be7e3b09f7c6e374074c20b2e0d652 100755 (executable)
Binary files a/onyx and b/onyx differ
index 01d59c54f4b98bc1d8547700b2759a6800e65b70..16eed850f6f2ddcd4dd84c244e350c93cbf04e87 100644 (file)
@@ -4,6 +4,8 @@
 #include "onyxutils.h"
 #include "onyxerrors.h"
 
+static u32 next_unique_id = 1;
+
 // NOTE: These have to be in the same order as Basic
 Type basic_types[] = {
     { Type_Kind_Basic, 0, { Basic_Kind_Void,                    0,                       0,  1, "void"   } },
@@ -331,6 +333,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             s_node->stcache = s_type;
             s_type->kind = Type_Kind_Struct;
 
+            s_type->Struct.unique_id = next_unique_id++;
             s_type->Struct.name = s_node->name;
             s_type->Struct.mem_count = bh_arr_length(s_node->members);
             s_type->Struct.memarr = NULL;
@@ -412,6 +415,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             enum_node->etcache = enum_type;
 
             enum_type->kind = Type_Kind_Enum;
+            enum_type->Enum.unique_id = next_unique_id++;
             enum_type->Enum.backing = enum_node->backing_type;
             enum_type->Enum.name = enum_node->name;
 
@@ -542,6 +546,49 @@ Type* type_make_varargs(bh_allocator alloc, Type* of) {
     return va_type;
 }
 
+const char* type_get_unique_name(Type* type) {
+    if (type == NULL) return "unknown";
+
+    switch (type->kind) {
+        case Type_Kind_Basic: return type->Basic.name;
+        case Type_Kind_Pointer: return bh_aprintf(global_scratch_allocator, "^%s", type_get_unique_name(type->Pointer.elem));
+        case Type_Kind_Array: return bh_aprintf(global_scratch_allocator, "[%d] %s", type->Array.count, type_get_unique_name(type->Array.elem));
+        case Type_Kind_Struct:
+            if (type->Struct.name)
+                return bh_aprintf(global_scratch_allocator, "%s@%l", type->Struct.name, type->Struct.unique_id);
+            else
+                return bh_aprintf(global_scratch_allocator, "%s@%l", "<anonymous struct>", type->Struct.unique_id);
+        case Type_Kind_Enum:
+            if (type->Enum.name)
+                return bh_aprintf(global_scratch_allocator, "%s@%l", type->Enum.name, type->Enum.unique_id);
+            else
+                return bh_aprintf(global_scratch_allocator, "%s@%l", "<anonymous enum>", type->Enum.unique_id);
+
+        case Type_Kind_Slice: return bh_aprintf(global_scratch_allocator, "[] %s", type_get_unique_name(type->Slice.ptr_to_data->Pointer.elem));
+        case Type_Kind_VarArgs: return bh_aprintf(global_scratch_allocator, "..%s", type_get_unique_name(type->VarArgs.ptr_to_data->Pointer.elem));
+        case Type_Kind_DynArray: return bh_aprintf(global_scratch_allocator, "[..] %s", type_get_unique_name(type->DynArray.ptr_to_data->Pointer.elem));
+
+        case Type_Kind_Function: {
+            char buf[512];
+            fori (i, 0, 512) buf[i] = 0;
+
+            strncat(buf, "proc (", 511);
+            fori (i, 0, type->Function.param_count) {
+                strncat(buf, type_get_unique_name(type->Function.params[i]), 511);
+                if (i != type->Function.param_count - 1)
+                    strncat(buf, ", ", 511);
+            }
+
+            strncat(buf, ") -> ", 511);
+            strncat(buf, type_get_unique_name(type->Function.return_type), 511);
+
+            return bh_aprintf(global_scratch_allocator, "%s", buf);
+        }
+
+        default: return "unknown";
+    }
+}
+
 const char* type_get_name(Type* type) {
     if (type == NULL) return "unknown";
 
index b1b3c51be5574fe7f3837a8b716df454ae26e982..9111404ea3c33e03c1c6014714198cb01db347f6 100644 (file)
@@ -579,7 +579,7 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lo
     bh_table_each_start(AstNode *, pp->poly_scope->symbols);
         strncat(key_buf, key, 1023);
         strncat(key_buf, "=", 1023);
-        strncat(key_buf, type_get_name(((AstTypeRawAlias *) value)->to), 1023);
+        strncat(key_buf, type_get_unique_name(((AstTypeRawAlias *) value)->to), 1023);
         strncat(key_buf, ";", 1023);
     bh_table_each_end;
 
@@ -658,7 +658,7 @@ AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(Type
     bh_table_each_start(AstNode *, ps_type->scope->symbols);
         strncat(key_buf, key, 1023);
         strncat(key_buf, "=", 1023);
-        strncat(key_buf, type_get_name(((AstTypeRawAlias *) value)->to), 1023);
+        strncat(key_buf, type_get_unique_name(((AstTypeRawAlias *) value)->to), 1023);
         strncat(key_buf, ";", 1023);
     bh_table_each_end;