diff options
Diffstat (limited to 'src/checker/expr.cpp')
| -rw-r--r-- | src/checker/expr.cpp | 116 |
1 files changed, 55 insertions, 61 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 6f9957408..24c61fb14 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -65,7 +65,6 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu Type *src = base_type(s); Type *dst = base_type(type); - if (is_type_untyped(src)) { switch (dst->kind) { case Type_Basic: @@ -86,11 +85,13 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu return true; } - if (is_type_pointer(dst) && is_type_rawptr(src)) + if (is_type_pointer(dst) && is_type_rawptr(src)) { return true; + } - if (is_type_rawptr(dst) && is_type_pointer(src)) + if (is_type_rawptr(dst) && is_type_pointer(src)) { return true; + } if (dst->kind == Type_Array && src->kind == Type_Array) { if (are_types_identical(dst->Array.elem, src->Array.elem)) { @@ -513,7 +514,6 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke struct_type->Record.fields = reordered_fields; } - } void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker *cycle_checker) { @@ -848,9 +848,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl // if (cycle_checker == NULL) { // cycle_checker = &local_cycle_checker; // } - // defer (if (local_cycle_checker.path != NULL) { - // gb_array_free(local_cycle_checker.path); - // }); + // defer (cycle_checker_destroy(&local_cycle_checker)); check_entity_decl(c, e, NULL, named_type, cycle_checker); @@ -939,8 +937,9 @@ i64 check_array_count(Checker *c, AstNode *e) { if (is_type_untyped(o.type) || is_type_integer(o.type)) { if (o.value.kind == ExactValue_Integer) { i64 count = o.value.value_integer; - if (count >= 0) + if (count >= 0) { return count; + } error(ast_node_token(e), "Invalid array count"); return 0; } @@ -966,8 +965,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c break; case Addressing_Type: { type = o.type; - type->flags |= e->type_flags; - set_base_type(named_type, type); goto end; } break; case Addressing_NoValue: @@ -991,9 +988,7 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c case Addressing_Type: GB_ASSERT(o.type != NULL); type = o.type; - type->flags |= e->type_flags; - set_base_type(named_type, type); - return type; + goto end; case Addressing_NoValue: err_str = expr_to_string(e); error(ast_node_token(e), "`%s` used as a type", err_str); @@ -1007,19 +1002,29 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c case_ast_node(pe, ParenExpr, e); type = check_type(c, pe->expr, named_type, cycle_checker); - type->flags |= e->type_flags; - return type; + goto end; + case_end; + + case_ast_node(ue, UnaryExpr, e); + if (ue->op.kind == Token_Pointer) { + type = make_type_pointer(c->allocator, check_type(c, ue->expr)); + goto end; + } + case_end; + + case_ast_node(pt, PointerType, e); + Type *elem = check_type(c, pt->type); + type = make_type_pointer(c->allocator, elem); + goto end; case_end; case_ast_node(at, ArrayType, e); if (at->count != NULL) { - type = make_type_array(c->allocator, - check_type(c, at->elem, NULL, cycle_checker), - check_array_count(c, at->count)); - set_base_type(named_type, type); + Type *elem = check_type(c, at->elem, NULL, cycle_checker); + type = make_type_array(c->allocator, elem, check_array_count(c, at->count)); } else { - type = make_type_slice(c->allocator, check_type(c, at->elem)); - set_base_type(named_type, type); + Type *elem = check_type(c, at->elem); + type = make_type_slice(c->allocator, elem); } goto end; case_end; @@ -1034,7 +1039,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c error(ast_node_token(vt->elem), "Vector element type must be numerical or a boolean. Got `%s`", err_str); } type = make_type_vector(c->allocator, elem, count); - set_base_type(named_type, type); goto end; case_end; @@ -1078,12 +1082,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c goto end; case_end; - case_ast_node(pt, PointerType, e); - type = make_type_pointer(c->allocator, check_type(c, pt->type)); - set_base_type(named_type, type); - goto end; - case_end; - case_ast_node(pt, ProcType, e); type = alloc_type(c->allocator, Type_Proc); set_base_type(named_type, type); @@ -1093,34 +1091,27 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c goto end; case_end; - default: { - if (e->kind == AstNode_CallExpr) { - Operand o = {}; - check_expr_or_type(c, &o, e); - if (o.mode == Addressing_Type) { - type = o.type; - goto end; - } - } else if (e->kind == AstNode_UnaryExpr) { - ast_node(ue, UnaryExpr, e); - if (ue->op.kind == Token_Pointer) { - type = make_type_pointer(c->allocator, check_type(c, ue->expr)); - set_base_type(named_type, type); - goto end; - } + case_ast_node(ce, CallExpr, e); + Operand o = {}; + check_expr_or_type(c, &o, e); + if (o.mode == Addressing_Type) { + type = o.type; + goto end; } - - err_str = expr_to_string(e); - error(ast_node_token(e), "`%s` is not a type", err_str); - } break; + case_end; } + err_str = expr_to_string(e); + error(ast_node_token(e), "`%s` is not a type", err_str); type = t_invalid; - set_base_type(named_type, type); - end: + if (type == NULL) { + type = t_invalid; + } + + set_base_type(named_type, type); GB_ASSERT(is_type_typed(type)); - type->flags |= e->type_flags; + add_type_and_value(&c->info, e, Addressing_Type, type, null_value); return type; } @@ -1550,19 +1541,13 @@ b32 check_is_castable_to(Checker *c, Operand *operand, Type *y) { return true; } - // // untyped integers -> pointers - // if (is_type_untyped(xb) && is_type_integer(xb)) { - // if (is_type_pointer(yb)) - // return true; - // } - // (u)int <-> pointer - if (is_type_pointer(xb) || (is_type_int_or_uint(xb) && !is_type_untyped(xb))) { + if (is_type_int_or_uint(xb) && !is_type_untyped(xb)) { if (is_type_pointer(yb)) return true; } if (is_type_pointer(xb)) { - if (is_type_pointer(yb) || (is_type_int_or_uint(yb) && !is_type_untyped(yb))) + if (is_type_int_or_uint(yb) && !is_type_untyped(yb)) return true; } @@ -1643,7 +1628,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { } } } else if (check_is_castable_to(c, x, type)) { - x->mode = Addressing_Value; + if (x->mode != Addressing_Constant) { + x->mode = Addressing_Value; + } can_convert = true; } @@ -3963,17 +3950,24 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_end; case_ast_node(st, StructType, node); - str = gb_string_appendc(str, "struct{"); + str = gb_string_appendc(str, "struct "); + if (st->is_packed) str = gb_string_appendc(str, "#packed "); + if (st->is_ordered) str = gb_string_appendc(str, "#ordered "); // str = write_fields_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); case_end; case_ast_node(st, RawUnionType, node); - str = gb_string_appendc(str, "raw_union{"); + str = gb_string_appendc(str, "raw_union {"); // str = write_fields_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); case_end; + case_ast_node(st, UnionType, node); + str = gb_string_appendc(str, "union {"); + // str = write_fields_to_string(str, st->decl_list, ", "); + str = gb_string_appendc(str, "}"); + case_end; case_ast_node(et, EnumType, node); str = gb_string_appendc(str, "enum "); |