From: Brendan Hansen Date: Tue, 5 Oct 2021 23:41:32 +0000 (-0500) Subject: added tagging to struct members X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ea50ac6ea267acdbf4e6a23a9d11fa86f094c5e6;p=onyx.git added tagging to struct members --- diff --git a/bin/onyx b/bin/onyx index 19e4efc7..e2c8f7cf 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/type_info/type_info.onyx b/core/type_info/type_info.onyx index d49dce44..530c5f9c 100644 --- a/core/type_info/type_info.onyx +++ b/core/type_info/type_info.onyx @@ -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; diff --git a/include/astnodes.h b/include/astnodes.h index 8be59f54..68f84477 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -791,6 +791,8 @@ struct AstStructType { struct AstStructMember { AstTyped_base; AstTyped* initial_value; + + bh_arr(AstTyped *) meta_tags; }; struct AstPolyStructParam { AstTyped_base; diff --git a/include/types.h b/include/types.h index 481dd3eb..cb9fb30b 100644 --- a/include/types.h +++ b/include/types.h @@ -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; diff --git a/src/checker.c b/src/checker.c index fd282119..642325df 100644 --- a/src/checker.c +++ b/src/checker.c @@ -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; diff --git a/src/parser.c b/src/parser.c index f3775b41..f7bef603 100644 --- a/src/parser.c +++ b/src/parser.c @@ -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; diff --git a/src/symres.c b/src/symres.c index ad8544e9..b771b308 100644 --- a/src/symres.c +++ b/src/symres.c @@ -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(); diff --git a/src/types.c b/src/types.c index c9d74d70..f303b9f0 100644 --- a/src/types.c +++ b/src/types.c @@ -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)) { diff --git a/src/wasm_type_table.c b/src/wasm_type_table.c index a930f1bb..b7d46bbf 100644 --- a/src/wasm_type_table.c +++ b/src/wasm_type_table.c @@ -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);