added tagging to struct members
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 5 Oct 2021 23:41:32 +0000 (18:41 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 5 Oct 2021 23:41:32 +0000 (18:41 -0500)
bin/onyx
core/type_info/type_info.onyx
include/astnodes.h
include/types.h
src/checker.c
src/parser.c
src/symres.c
src/types.c
src/wasm_type_table.c

index 19e4efc76bfeb14c46b4f953507dad8a6659f44a..e2c8f7cfa40673f4c3ac24581bedcea6b5fe4175 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index d49dce44609a9e7b29f85609409d60c1eb14fc45..530c5f9cf5acb46d11ac32e603d3eecee227917c 100644 (file)
@@ -141,6 +141,8 @@ Type_Info_Struct :: struct {
 
                          // As another thought. This could become a thunk that get the default value
                          // at runtime or returns the value.
+
+        tags: [] any;
     }
 
     name: str;
index 8be59f5480788d2b54178e6557aa166fd7a89b27..68f84477bc4df76e94d545cc136b20a829572e4a 100644 (file)
@@ -791,6 +791,8 @@ struct AstStructType {
 struct AstStructMember {
     AstTyped_base;
     AstTyped* initial_value;
+
+    bh_arr(AstTyped *) meta_tags;
 };
 struct AstPolyStructParam {
     AstTyped_base;
index 481dd3eb845fa3759aee2b94444a1d0710de2731..cb9fb30b0872bbd15eff6c258c67b8e6db634d83 100644 (file)
@@ -78,6 +78,8 @@ typedef struct StructMember {
     struct AstTyped** initial_value;
     b32 included_through_use : 1;
     b32 used : 1;
+
+    bh_arr(struct AstTyped *) meta_tags;
 } StructMember;
 
 typedef struct TypeWithOffset TypeWithOffset;
index fd282119ac225eb71d132a87f19a0e64bb896b82..642325df5e58c9a41d7bb56291a88b84b735bf05 100644 (file)
@@ -1905,6 +1905,18 @@ CheckStatus check_struct_defaults(AstStructType* s_node) {
 
             resolve_expression_type(*(*smem)->initial_value);
         }
+
+        if ((*smem)->meta_tags) {
+            bh_arr_each(AstTyped *, meta, (*smem)->meta_tags) {
+                CHECK(expression, meta);
+                resolve_expression_type(*meta);
+
+                if (((*meta)->flags & Ast_Flag_Comptime) == 0) {
+                    onyx_report_error((*meta)->token->pos, "#meta expression are expected to be compile-time known.");
+                    return Check_Error;
+                }
+            }
+        }
     }
 
     return Check_Success;
index f3775b41d9e47ac2f67798f55bf4ca166f1a6101..f7bef603b32a7a440d30a197a2eaaa9ef93176d1 100644 (file)
@@ -1931,6 +1931,16 @@ static AstStructType* parse_struct(OnyxParser* parser) {
             consume_token_if_next(parser, ';');
 
         } else {
+            bh_arr(AstTyped *) meta_tags=NULL;
+            while (parse_possible_directive(parser, "tag")) {
+                AstTyped* expr = parse_expression(parser, 0);
+
+                if (meta_tags == NULL) bh_arr_new(global_heap_allocator, meta_tags, 1);
+                bh_arr_push(meta_tags, expr);
+
+                expect_token(parser, ';');
+            }
+
             bh_arr_clear(member_list_temp);
             while (!consume_token_if_next(parser, ':')) {
                 if (parser->hit_unexpected_token) return NULL;
@@ -1968,6 +1978,7 @@ static AstStructType* parse_struct(OnyxParser* parser) {
                 mem->token = *member_name;
                 mem->type_node = member_type;
                 mem->initial_value = initial_value;
+                mem->meta_tags = meta_tags;
 
                 if (member_is_used) mem->flags |= Ast_Flag_Struct_Mem_Used;
 
index ad8544e98b24111324b12a232030737b9342faaa..b771b308fe42d96c757eb5c47166690f34ee8553 100644 (file)
@@ -1066,6 +1066,12 @@ static SymresStatus symres_struct_defaults(AstType* t) {
         if ((*smem)->initial_value != NULL) {
             SYMRES(expression, &(*smem)->initial_value);
         }
+
+        if ((*smem)->meta_tags != NULL) {
+            bh_arr_each(AstTyped *, meta, (*smem)->meta_tags) {
+                SYMRES(expression, meta);
+            }
+        }
     }
 
     if (st->scope) scope_leave();
index c9d74d70b2e57dcf35021966f0a7b06fd2485be4..f303b9f0adab532f025d56ed1ca194ad88079b70 100644 (file)
@@ -381,6 +381,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
                     .initial_value = &(*member)->initial_value,
                     .included_through_use = 0,
                     .used = (((*member)->flags & Ast_Flag_Struct_Mem_Used) != 0),
+                    .meta_tags = (*member)->meta_tags,
                 };
 
                 if (bh_table_has(StructMember, s_type->Struct.members, (*member)->token->text)) {
@@ -402,6 +403,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
                             .initial_value = (*psmem)->initial_value,
                             .included_through_use = 1,
                             .used = 0,
+                            .meta_tags = (*psmem)->meta_tags,
                         };
 
                         if (bh_table_has(StructMember, s_type->Struct.members, (*psmem)->name)) {
index a930f1bb5060074738bf5d0a06a81614604e0ce2..b7d46bbf7d347bb9ec4aed4baf4a798ec64ad09c 100644 (file)
@@ -174,7 +174,9 @@ u64 build_type_table(OnyxWasmModule* module) {
                 u32* name_locations = bh_alloc_array(global_scratch_allocator, u32, s->mem_count);
                 u32* param_locations = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(s->poly_sln));
                 u32* value_locations = bh_alloc_array(global_scratch_allocator, u32, s->mem_count);
+                u32* meta_locations = bh_alloc_array(global_scratch_allocator, u32, s->mem_count);
                 memset(value_locations, 0, s->mem_count * sizeof(u32));
+                memset(meta_locations, 0, s->mem_count * sizeof(u32));
 
                 u32 i = 0;
                 bh_arr_each(StructMember*, pmem, s->memarr) {
@@ -255,6 +257,53 @@ u64 build_type_table(OnyxWasmModule* module) {
                     }
                 }
 
+                i = 0;
+                bh_arr_each(StructMember*, pmem, s->memarr) {
+                    StructMember* mem = *pmem;
+
+                    if (mem->meta_tags == NULL) {
+                        i += 1;
+                        continue;
+                    }
+
+                    bh_arr(AstTyped *) meta_tags = mem->meta_tags;
+                    assert(meta_tags);
+
+                    bh_arr(u64) meta_tag_locations=NULL;
+                    bh_arr_new(global_heap_allocator, meta_tag_locations, bh_arr_length(meta_tags));
+
+                    int j = 0;
+                    bh_arr_each(AstTyped *, meta, meta_tags) {
+                        AstTyped* value = *meta;                        
+                        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));
+                        meta_tag_locations[j] = 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;
+
+                        j += 1;
+                    }
+
+                    bh_buffer_align(&table_buffer, 8);
+                    meta_locations[i] = table_buffer.length;
+
+                    fori (k, 0, bh_arr_length(meta_tags)) {
+                        PATCH;
+                        bh_buffer_write_u64(&table_buffer, meta_tag_locations[k]);
+                        bh_buffer_write_u64(&table_buffer, meta_tags[k]->type->id);
+                    }
+
+                    bh_arr_free(meta_tag_locations);
+                    i += 1;
+                }
+
                 bh_buffer_align(&table_buffer, 8);
                 u32 members_base = table_buffer.length;
 
@@ -263,7 +312,8 @@ u64 build_type_table(OnyxWasmModule* module) {
                     StructMember* mem = *pmem;
 
                     u32 name_loc = name_locations[i];
-                    u32 value_loc = value_locations[i++];
+                    u32 value_loc = value_locations[i];
+                    u32 meta_loc = meta_locations[i++];
 
                     bh_buffer_align(&table_buffer, 8);
                     PATCH;
@@ -276,6 +326,10 @@ u64 build_type_table(OnyxWasmModule* module) {
                     bh_buffer_align(&table_buffer, 8);
                     PATCH;
                     bh_buffer_write_u64(&table_buffer, value_loc);
+
+                    PATCH;
+                    bh_buffer_write_u64(&table_buffer, meta_loc);
+                    bh_buffer_write_u64(&table_buffer, bh_arr_length(mem->meta_tags));
                 }
 
                 bh_buffer_align(&table_buffer, 8);