From: Brendan Hansen Date: Wed, 6 Oct 2021 19:43:54 +0000 (-0500) Subject: structs can have tags; some bugfixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=af7c45e73a0b99d93a04bbe27e462714f552234d;p=onyx.git structs can have tags; some bugfixes --- diff --git a/bin/onyx b/bin/onyx index e2c8f7cf..1012a7e8 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 530c5f9c..558ba45f 100644 --- a/core/type_info/type_info.onyx +++ b/core/type_info/type_info.onyx @@ -148,6 +148,7 @@ Type_Info_Struct :: struct { name: str; members: [] Member; parameters: [] any; + tags: [] any; } Type_Info_Compound :: struct { diff --git a/include/astnodes.h b/include/astnodes.h index 68f84477..02f0c1be 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -772,6 +772,7 @@ struct AstStructType { char *name; bh_arr(AstStructMember *) members; + bh_arr(AstTyped *) meta_tags; u32 min_alignment, min_size; diff --git a/include/types.h b/include/types.h index cb9fb30b..9e2961b3 100644 --- a/include/types.h +++ b/include/types.h @@ -107,6 +107,7 @@ struct TypeWithOffset { bh_arr(struct AstPolySolution) poly_sln; \ bh_arr(TypeWithOffset) linear_members; \ struct AstType *constructed_from; \ + bh_arr(struct AstTyped *) meta_tags; \ }) \ TYPE_KIND(Compound, struct { \ u32 count; \ diff --git a/modules/immediate_mode/immediate_renderer.onyx b/modules/immediate_mode/immediate_renderer.onyx index ccdf9acb..03718ce3 100644 --- a/modules/immediate_mode/immediate_renderer.onyx +++ b/modules/immediate_mode/immediate_renderer.onyx @@ -313,9 +313,9 @@ Immediate_Renderer :: struct { new_w := new_x1 - new_x0; new_h := new_y1 - new_y0; - array.push(^scissor_stack, .{ new_x0, new_y0, new_w, new_h }); + array.push(^scissor_stack, .{ new_x0, new_y0, new_w + 1, new_h + 1 }); - gl.scissor(~~new_x0, window_height - ~~new_y1, ~~new_w, ~~new_h); + gl.scissor(~~new_x0, window_height - ~~new_y1, ~~math.ceil(new_w + 1), ~~math.ceil(new_h + 1)); } pop_scissor :: (use ir: ^Immediate_Renderer) { diff --git a/modules/ui/components/scrollable_region.onyx b/modules/ui/components/scrollable_region.onyx index eca3fd89..c9463194 100644 --- a/modules/ui/components/scrollable_region.onyx +++ b/modules/ui/components/scrollable_region.onyx @@ -35,8 +35,9 @@ Scrollable_Region_Handle :: struct { } scrollable_region_start :: (use r: Rectangle, use src: Scrollable_Region_Controls = .{}, - site := #callsite, state: ^Scrollable_Region_State = null) -> Scrollable_Region_Handle { - hash := get_site_hash(site, 0); + site := #callsite, increment := 0, + state: ^Scrollable_Region_State = null) -> Scrollable_Region_Handle { + hash := get_site_hash(site, increment); x, y := Rectangle.top_left(r); width, height := Rectangle.dimensions(r); diff --git a/src/checker.c b/src/checker.c index 642325df..57586d73 100644 --- a/src/checker.c +++ b/src/checker.c @@ -1253,18 +1253,20 @@ CheckStatus check_address_of(AstAddressOf* aof) { YIELD(aof->token->pos, "Trying to resolve type of expression to take a reference."); } - if ((aof->expr->kind != Ast_Kind_Subscript - && aof->expr->kind != Ast_Kind_Dereference - && aof->expr->kind != Ast_Kind_Field_Access - && aof->expr->kind != Ast_Kind_Memres - && aof->expr->kind != Ast_Kind_Local) - || (aof->expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) { + AstTyped* expr = (AstTyped *) strip_aliases((AstNode *) aof->expr); + + if ((expr->kind != Ast_Kind_Subscript + && expr->kind != Ast_Kind_Dereference + && expr->kind != Ast_Kind_Field_Access + && expr->kind != Ast_Kind_Memres + && expr->kind != Ast_Kind_Local) + || (expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) { ERROR(aof->token->pos, "Cannot take the address of something that is not an l-value."); } - aof->expr->flags |= Ast_Flag_Address_Taken; + expr->flags |= Ast_Flag_Address_Taken; - aof->type = type_make_pointer(context.ast_alloc, aof->expr->type); + aof->type = type_make_pointer(context.ast_alloc, expr->type); return Check_Success; } @@ -1892,6 +1894,18 @@ CheckStatus check_struct_defaults(AstStructType* s_node) { if (s_node->entity_type && s_node->entity_type->state < Entity_State_Code_Gen) YIELD(s_node->token->pos, "Waiting for struct type to be constructed before checking defaulted members."); + if (s_node->meta_tags) { + bh_arr_each(AstTyped *, meta, s_node->meta_tags) { + CHECK(expression, meta); + resolve_expression_type(*meta); + + if (((*meta)->flags & Ast_Flag_Comptime) == 0) { + onyx_report_error((*meta)->token->pos, "#tag expressions are expected to be compile-time known."); + return Check_Error; + } + } + } + bh_arr_each(StructMember *, smem, s_node->stcache->Struct.memarr) { if ((*smem)->initial_value && *(*smem)->initial_value) { CHECK(expression, (*smem)->initial_value); @@ -1912,7 +1926,7 @@ CheckStatus check_struct_defaults(AstStructType* s_node) { 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."); + onyx_report_error((*meta)->token->pos, "#tag expressions are expected to be compile-time known."); return Check_Error; } } @@ -2057,6 +2071,7 @@ CheckStatus check_memres(AstMemRes* memres) { CheckStatus check_type(AstType* type) { if (type == NULL) return Check_Success; + AstType* original_type = type; while (type->kind == Ast_Kind_Type_Alias) type = ((AstTypeAlias *) type)->to; @@ -2126,6 +2141,12 @@ CheckStatus check_type(AstType* type) { } } + type = original_type; + while (type->kind == Ast_Kind_Type_Alias) { + type->flags |= Ast_Flag_Comptime; + type = ((AstTypeAlias *) type)->to; + } + type->flags |= Ast_Flag_Already_Checked; return Check_Success; } diff --git a/src/parser.c b/src/parser.c index f7bef603..38762521 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1782,6 +1782,7 @@ static AstType* parse_type(OnyxParser* parser) { case Token_Type_Literal_Float: case Token_Type_Literal_True: case Token_Type_Literal_False: + case '-': *next_insertion = (AstType *) parse_expression(parser, 0); next_insertion = NULL; break; @@ -1875,7 +1876,8 @@ static AstStructType* parse_struct(OnyxParser* parser) { } bh_arr_new(global_heap_allocator, s_node->members, 4); - + + bh_arr(AstTyped *) struct_meta_tags=NULL; while (parser->curr->type == '#') { if (parser->hit_unexpected_token) return NULL; @@ -1897,6 +1899,17 @@ static AstStructType* parse_struct(OnyxParser* parser) { s_node->min_size = numlit->value.i; } + else if (parse_possible_directive(parser, "tag")) { + expect_token(parser, '('); + + AstTyped* expr = parse_expression(parser, 0); + + if (struct_meta_tags == NULL) bh_arr_new(global_heap_allocator, struct_meta_tags, 1); + bh_arr_push(struct_meta_tags, expr); + + expect_token(parser, ')'); + } + else { OnyxToken* directive_token = expect_token(parser, '#'); OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol); @@ -1905,6 +1918,8 @@ static AstStructType* parse_struct(OnyxParser* parser) { } } + s_node->meta_tags = struct_meta_tags; + expect_token(parser, '{'); b32 member_is_used = 0; @@ -1933,12 +1948,14 @@ static AstStructType* parse_struct(OnyxParser* parser) { } else { bh_arr(AstTyped *) meta_tags=NULL; while (parse_possible_directive(parser, "tag")) { + expect_token(parser, '('); + 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, ';'); + expect_token(parser, ')'); } bh_arr_clear(member_list_temp); diff --git a/src/symres.c b/src/symres.c index b771b308..97c7702c 100644 --- a/src/symres.c +++ b/src/symres.c @@ -1062,6 +1062,12 @@ static SymresStatus symres_struct_defaults(AstType* t) { AstStructType* st = (AstStructType *) t; if (st->scope) scope_enter(st->scope); + if (st->meta_tags) { + bh_arr_each(AstTyped *, meta, st->meta_tags) { + SYMRES(expression, meta); + } + } + bh_arr_each(AstStructMember *, smem, st->members) { if ((*smem)->initial_value != NULL) { SYMRES(expression, &(*smem)->initial_value); diff --git a/src/types.c b/src/types.c index f303b9f0..7b8451de 100644 --- a/src/types.c +++ b/src/types.c @@ -330,6 +330,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { s_type->ast_type = type_node; s_type->Struct.name = s_node->name; s_type->Struct.mem_count = bh_arr_length(s_node->members); + s_type->Struct.meta_tags = s_node->meta_tags; type_register(s_type); s_type->Struct.memarr = NULL; diff --git a/src/wasm.c b/src/wasm.c index 3d43d6c4..a2861317 100644 --- a/src/wasm.c +++ b/src/wasm.c @@ -491,6 +491,19 @@ EMIT_FUNC(assignment, AstBinaryOp* assign) { } } + if (lval->kind == Ast_Kind_Field_Access) { + AstFieldAccess* fa = (AstFieldAccess *) lval; + if (fa->expr->kind == Ast_Kind_Param && type_is_structlike_strict(fa->expr->type)) { + emit_expression(mod, &code, assign->right); + + u64 localidx = bh_imap_get(&mod->local_map, (u64) fa->expr); + WIL(WI_LOCAL_SET, localidx + fa->idx); + + *pcode = code; + return; + } + } + if (lval->kind == Ast_Kind_Global) { emit_expression(mod, &code, assign->right); @@ -2368,6 +2381,8 @@ EMIT_FUNC(do_block, AstDoBlock* doblock) { EMIT_FUNC(location_return_offset, AstTyped* expr, u64* offset_return) { bh_arr(WasmInstruction) code = *pcode; + expr = (AstTyped *) strip_aliases((AstNode *) expr); + switch (expr->kind) { case Ast_Kind_Param: case Ast_Kind_Local: { @@ -3305,6 +3320,12 @@ static void emit_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) { static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node) { b32 retval = 1; + if (node_is_type((AstNode *) node)) { + Type* constructed_type = type_build_from_ast(context.ast_alloc, (AstType *) node); + ((i32 *) data)[0] = constructed_type->id; + return 1; + } + switch (node->kind) { case Ast_Kind_Array_Literal: { AstArrayLiteral* al = (AstArrayLiteral *) node; diff --git a/src/wasm_type_table.c b/src/wasm_type_table.c index b7d46bbf..236602ca 100644 --- a/src/wasm_type_table.c +++ b/src/wasm_type_table.c @@ -175,8 +175,10 @@ u64 build_type_table(OnyxWasmModule* module) { 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); + u32* struct_tag_locations = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(s->meta_tags)); memset(value_locations, 0, s->mem_count * sizeof(u32)); memset(meta_locations, 0, s->mem_count * sizeof(u32)); + memset(struct_tag_locations, 0, bh_arr_length(s->meta_tags) * sizeof(u32)); u32 i = 0; bh_arr_each(StructMember*, pmem, s->memarr) { @@ -345,6 +347,34 @@ u64 build_type_table(OnyxWasmModule* module) { else bh_buffer_write_u32(&table_buffer, sln->value->type->id); } + i = 0; + bh_arr_each(AstTyped *, tag, s->meta_tags) { + AstTyped* value = *tag; + 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)); + struct_tag_locations[i] = 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; + + i += 1; + } + + bh_buffer_align(&table_buffer, 8); + u32 struct_tag_base = table_buffer.length; + + fori (i, 0, bh_arr_length(s->meta_tags)) { + PATCH; + bh_buffer_write_u64(&table_buffer, struct_tag_locations[i]); + bh_buffer_write_u64(&table_buffer, s->meta_tags[i]->type->id); + } + u32 name_base = 0; u32 name_length = 0; if (s->name) { @@ -368,6 +398,9 @@ u64 build_type_table(OnyxWasmModule* module) { PATCH; bh_buffer_write_u64(&table_buffer, params_base); bh_buffer_write_u64(&table_buffer, bh_arr_length(s->poly_sln)); + PATCH; + bh_buffer_write_u64(&table_buffer, struct_tag_base); + bh_buffer_write_u64(&table_buffer, bh_arr_length(s->meta_tags)); break; }