From: Brendan Hansen Date: Tue, 30 Nov 2021 00:41:09 +0000 (-0600) Subject: code cleanup; fixed slice creation bug X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=898f8040d21a79d32c09fc1d10df59ef376bd523;p=onyx.git code cleanup; fixed slice creation bug --- diff --git a/include/types.h b/include/types.h index 374d2fd0..999443c5 100644 --- a/include/types.h +++ b/include/types.h @@ -200,6 +200,7 @@ void build_linear_types_with_offset(Type* type, bh_arr(TypeWithOffset)* pdest, u const char* type_get_unique_name(Type* type); const char* type_get_name(Type* type); u32 type_get_alignment_log2(Type* type); +Type* type_get_contained_type(Type* type); b32 type_lookup_member(Type* type, char* member, StructMember* smem); b32 type_lookup_member_by_idx(Type* type, i32 idx, StructMember* smem); diff --git a/src/checker.c b/src/checker.c index 03da8f75..e2208cc1 100644 --- a/src/checker.c +++ b/src/checker.c @@ -1430,13 +1430,22 @@ CheckStatus check_subscript(AstSubscript** psub) { return Check_Error; } + if (sub->addr->type->kind == Type_Kind_Slice || sub->addr->type->kind == Type_Kind_DynArray || sub->addr->type->kind == Type_Kind_VarArgs) { + // If we are accessing on a slice or a dynamic array, implicitly add a field access for the data member + StructMember smem; + type_lookup_member(sub->addr->type, "data", &smem); + + AstFieldAccess* fa = make_field_access(context.ast_alloc, sub->addr, "data"); + fa->type = smem.type; + fa->offset = smem.offset; + fa->idx = smem.idx; + + sub->addr = (AstTyped *) fa; + } + if (types_are_compatible(sub->expr->type, builtin_range_type_type)) { - Type *of = NULL; - if (sub->addr->type->kind == Type_Kind_Pointer) - of = sub->addr->type->Pointer.elem; - else if (sub->addr->type->kind == Type_Kind_Array) - of = sub->addr->type->Array.elem; - else { + Type *of = type_get_contained_type(sub->addr->type); + if (of == NULL) { // FIXME: Slice creation should be allowed for slice types and dynamic array types, like it // is below, but this code doesn't look at that. report_bad_binaryop((AstBinaryOp *) sub); @@ -1451,40 +1460,18 @@ CheckStatus check_subscript(AstSubscript** psub) { } resolve_expression_type(sub->expr); - if (sub->expr->type->kind != Type_Kind_Basic - || (sub->expr->type->Basic.kind != Basic_Kind_I32 && sub->expr->type->Basic.kind != Basic_Kind_U32)) { + if (!type_is_small_integer(sub->expr->type)) { report_bad_binaryop((AstBinaryOp *) sub); - ERROR_(sub->token->pos, - "Expected type u32 or i32 for index, got '%s'.", - node_get_type_name(sub->expr)); - } - - if (sub->addr->type->kind == Type_Kind_Pointer) - sub->type = sub->addr->type->Pointer.elem; - else if (sub->addr->type->kind == Type_Kind_Array) - sub->type = sub->addr->type->Array.elem; - else if (sub->addr->type->kind == Type_Kind_Slice - || sub->addr->type->kind == Type_Kind_DynArray - || sub->addr->type->kind == Type_Kind_VarArgs) { - // If we are accessing on a slice or a dynamic array, implicitly add a field access for the data member - StructMember smem; - type_lookup_member(sub->addr->type, "data", &smem); - - AstFieldAccess* fa = make_field_access(context.ast_alloc, sub->addr, "data"); - fa->type = smem.type; - fa->offset = smem.offset; - fa->idx = smem.idx; - - sub->addr = (AstTyped *) fa; - sub->type = sub->addr->type->Pointer.elem; + ERROR_(sub->token->pos, "Expected small integer type for index, got '%s'.", node_get_type_name(sub->expr)); } - else { + + sub->type = type_get_contained_type(sub->addr->type); + if (sub->type == NULL) { report_bad_binaryop((AstBinaryOp *) sub); ERROR(sub->token->pos, "Invalid type for left of array access."); } sub->elem_size = type_size_of(sub->type); - return Check_Success; } @@ -1536,16 +1523,9 @@ CheckStatus check_field_access(AstFieldAccess** pfield) { char* closest = find_closest_symbol_in_node((AstNode *) type_node, field->field); if (closest) { - ERROR_(field->token->pos, - "Field '%s' does not exists on '%s'. Did you mean '%s'?", - field->field, - node_get_type_name(field->expr), - closest); + ERROR_(field->token->pos, "Field '%s' does not exists on '%s'. Did you mean '%s'?", field->field, node_get_type_name(field->expr), closest); } else { - ERROR_(field->token->pos, - "Field '%s' does not exists on '%s'.", - field->field, - node_get_type_name(field->expr)); + ERROR_(field->token->pos, "Field '%s' does not exists on '%s'.", field->field, node_get_type_name(field->expr)); } } @@ -1556,20 +1536,19 @@ CheckStatus check_field_access(AstFieldAccess** pfield) { return Check_Success; } -CheckStatus check_method_call(AstBinaryOp** mcall) { - CHECK(expression, &(*mcall)->left); - if ((*mcall)->left->type == NULL) { - YIELD((*mcall)->token->pos, "Trying to resolve type of left hand side."); - } +CheckStatus check_method_call(AstBinaryOp** pmcall) { + AstBinaryOp* mcall = *pmcall + CHECK(expression, &mcall->left); + if (mcall->left->type == NULL) YIELD((*mcall)->token->pos, "Trying to resolve type of left hand side."); - AstTyped* implicit_argument = (*mcall)->left; + AstTyped* implicit_argument = mcall->left; // Symbol resolution should have ensured that this is call node. - AstCall* call_node = (AstCall *) (*mcall)->right; + AstCall* call_node = (AstCall *) mcall->right; assert(call_node->kind == Ast_Kind_Call); // :Idempotency - if (((*mcall)->flags & Ast_Flag_Has_Been_Checked) == 0) { + if ((mcall->flags & Ast_Flag_Has_Been_Checked) == 0) { // Implicitly take the address of the value if it is not already a pointer type. // This could be weird to think about semantically so some testing with real code // would be good. - brendanfh 2020/02/05 @@ -1581,12 +1560,12 @@ CheckStatus check_method_call(AstBinaryOp** mcall) { bh_arr_insertn(call_node->args.values, 0, 1); call_node->args.values[0] = implicit_argument; } - (*mcall)->flags |= Ast_Flag_Has_Been_Checked; + mcall->flags |= Ast_Flag_Has_Been_Checked; CHECK(call, &call_node); - call_node->next = (*mcall)->next; + call_node->next = mcall->next; - *mcall = (AstBinaryOp *) call_node; + *pmcall = (AstBinaryOp *) call_node; return Check_Success; } diff --git a/src/types.c b/src/types.c index 84fa1772..2a3a5d92 100644 --- a/src/types.c +++ b/src/types.c @@ -987,6 +987,18 @@ u32 type_get_alignment_log2(Type* type) { return 2; } +Type* type_get_contained_type(Type* type) { + if (type == NULL) return NULL; + switch (type->kind) { + case Type_Kind_Pointer: return type->Pointer.elem; + case Type_Kind_Array: return type->Array.elem; + case Type_Kind_Slice: return type->Slice.elem; + case Type_Kind_DynArray: return type->DynArray.elem; + case Type_Kind_VarArgs: return type->VarArgs.elem; + default: return NULL; + } +} + static const StructMember slice_members[] = { { 0, 0, NULL, "data", NULL, 0, 0 }, { 8, 1, &basic_types[Basic_Kind_U32], "count", NULL, 0, 0 },